Pseudocode: Translate instruction classes to Kotlin
This commit is contained in:
@@ -1,4 +1,13 @@
|
|||||||
<root>
|
<root>
|
||||||
|
<item name='com.google.common.collect.Lists java.util.ArrayList<E> newArrayList(E...)'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
|
<item name='com.google.common.collect.Lists java.util.ArrayList<E> newArrayList(java.lang.Iterable<? extends E>)'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
|
<item name='com.google.common.collect.Maps java.util.LinkedHashMap<K,V> newLinkedHashMap()'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
<item name='com.google.common.collect.Multimap java.util.Set<K> keySet()'>
|
<item name='com.google.common.collect.Multimap java.util.Set<K> keySet()'>
|
||||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
</item>
|
</item>
|
||||||
@@ -9,4 +18,7 @@
|
|||||||
name='com.google.common.collect.Sets com.google.common.collect.Sets.SetView<E> intersection(java.util.Set<E>, java.util.Set<?>)'>
|
name='com.google.common.collect.Sets com.google.common.collect.Sets.SetView<E> intersection(java.util.Set<E>, java.util.Set<?>)'>
|
||||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
</item>
|
</item>
|
||||||
|
<item name='com.google.common.collect.Sets java.util.HashSet<E> newHashSet(java.lang.Iterable<? extends E>)'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
</root>
|
</root>
|
||||||
@@ -16,6 +16,9 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.lang.cfg;
|
package org.jetbrains.jet.lang.cfg;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public interface Label {
|
public interface Label {
|
||||||
|
@NotNull
|
||||||
String getName();
|
String getName();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ fun Pseudocode.traverse(
|
|||||||
val instructions = getInstructions(traversalOrder)
|
val instructions = getInstructions(traversalOrder)
|
||||||
for (instruction in instructions) {
|
for (instruction in instructions) {
|
||||||
if (instruction is LocalFunctionDeclarationInstruction) {
|
if (instruction is LocalFunctionDeclarationInstruction) {
|
||||||
instruction.getBody().traverse(traversalOrder, analyzeInstruction)
|
instruction.body.traverse(traversalOrder, analyzeInstruction)
|
||||||
}
|
}
|
||||||
analyzeInstruction(instruction)
|
analyzeInstruction(instruction)
|
||||||
}
|
}
|
||||||
@@ -41,7 +41,7 @@ fun <D> Pseudocode.traverse(
|
|||||||
val instructions = getInstructions(traversalOrder)
|
val instructions = getInstructions(traversalOrder)
|
||||||
for (instruction in instructions) {
|
for (instruction in instructions) {
|
||||||
if (instruction is LocalFunctionDeclarationInstruction) {
|
if (instruction is LocalFunctionDeclarationInstruction) {
|
||||||
instruction.getBody().traverse(traversalOrder, edgesMap, analyzeInstruction)
|
instruction.body.traverse(traversalOrder, edgesMap, analyzeInstruction)
|
||||||
}
|
}
|
||||||
val edges = edgesMap.get(instruction)
|
val edges = edgesMap.get(instruction)
|
||||||
if (edges != null) {
|
if (edges != null) {
|
||||||
@@ -81,7 +81,7 @@ private fun <D> Pseudocode.initializeEdgesMap(
|
|||||||
for (instruction in instructions) {
|
for (instruction in instructions) {
|
||||||
edgesMap.put(instruction, initialEdge)
|
edgesMap.put(instruction, initialEdge)
|
||||||
if (instruction is LocalFunctionDeclarationInstruction) {
|
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) {
|
if (instruction is LocalFunctionDeclarationInstruction) {
|
||||||
val subroutinePseudocode = instruction.getBody()
|
val subroutinePseudocode = instruction.body
|
||||||
val previous = if (mergeDataWithLocalDeclarations) previousInstructions else Collections.emptyList()
|
val previous = if (mergeDataWithLocalDeclarations) previousInstructions else Collections.emptyList()
|
||||||
subroutinePseudocode.collectDataFromSubgraph(
|
subroutinePseudocode.collectDataFromSubgraph(
|
||||||
traversalOrder, mergeDataWithLocalDeclarations,
|
traversalOrder, mergeDataWithLocalDeclarations,
|
||||||
@@ -208,10 +208,10 @@ fun Pseudocode.getInstructions(traversalOrder: TraversalOrder): MutableList<Inst
|
|||||||
if (traversalOrder == FORWARD) getInstructions() else getReversedInstructions()
|
if (traversalOrder == FORWARD) getInstructions() else getReversedInstructions()
|
||||||
|
|
||||||
fun Instruction.getNextInstructions(traversalOrder: TraversalOrder): Collection<Instruction> =
|
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> =
|
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 =
|
fun Instruction.isStartInstruction(traversalOrder: TraversalOrder): Boolean =
|
||||||
if (traversalOrder == FORWARD) this is SubroutineEnterInstruction else this is SubroutineSinkInstruction
|
if (traversalOrder == FORWARD) this is SubroutineEnterInstruction else this is SubroutineSinkInstruction
|
||||||
|
|||||||
@@ -60,8 +60,8 @@ public class PseudocodeVariableDataCollector(
|
|||||||
data: Map<VariableDescriptor, D>
|
data: Map<VariableDescriptor, D>
|
||||||
): 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.
|
// 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
|
val toDepth = to.lexicalScope.depth
|
||||||
if (toDepth >= from.getLexicalScope().depth) return data
|
if (toDepth >= from.lexicalScope.depth) return data
|
||||||
|
|
||||||
// Variables declared in an inner (deeper) scope can't be accessed from an outer scope.
|
// 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.
|
// Thus they can be filtered out upon leaving the inner scope.
|
||||||
@@ -77,14 +77,14 @@ public class PseudocodeVariableDataCollector(
|
|||||||
val lexicalScopeVariableInfo = LexicalScopeVariableInfoImpl()
|
val lexicalScopeVariableInfo = LexicalScopeVariableInfoImpl()
|
||||||
pseudocode.traverse(TraversalOrder.FORWARD, { instruction ->
|
pseudocode.traverse(TraversalOrder.FORWARD, { instruction ->
|
||||||
if (instruction is VariableDeclarationInstruction) {
|
if (instruction is VariableDeclarationInstruction) {
|
||||||
val variableDeclarationElement = instruction.getVariableDeclarationElement()
|
val variableDeclarationElement = instruction.variableDeclarationElement
|
||||||
val descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, variableDeclarationElement)
|
val descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, variableDeclarationElement)
|
||||||
if (descriptor != null) {
|
if (descriptor != null) {
|
||||||
assert(descriptor is VariableDescriptor,
|
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")
|
"Descriptor : $descriptor")
|
||||||
lexicalScopeVariableInfo.registerVariableDeclaredInScope(
|
lexicalScopeVariableInfo.registerVariableDeclaredInScope(
|
||||||
descriptor as VariableDescriptor, instruction.getLexicalScope())
|
descriptor as VariableDescriptor, instruction.lexicalScope)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -36,37 +36,37 @@ public class TailRecursionDetector extends InstructionVisitorWithResult<Boolean>
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Boolean visitInstruction(Instruction instruction) {
|
public Boolean visitInstruction(@NotNull Instruction instruction) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Boolean visitSubroutineExit(SubroutineExitInstruction instruction) {
|
public Boolean visitSubroutineExit(@NotNull SubroutineExitInstruction instruction) {
|
||||||
return !instruction.isError() && instruction.getSubroutine() == subroutine;
|
return !instruction.getIsError() && instruction.getSubroutine() == subroutine;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Boolean visitSubroutineSink(SubroutineSinkInstruction instruction) {
|
public Boolean visitSubroutineSink(@NotNull SubroutineSinkInstruction instruction) {
|
||||||
return instruction.getSubroutine() == subroutine;
|
return instruction.getSubroutine() == subroutine;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Boolean visitJump(AbstractJumpInstruction instruction) {
|
public Boolean visitJump(@NotNull AbstractJumpInstruction instruction) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Boolean visitThrowExceptionInstruction(ThrowExceptionInstruction instruction) {
|
public Boolean visitThrowExceptionInstruction(@NotNull ThrowExceptionInstruction instruction) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Boolean visitMarkInstruction(MarkInstruction instruction) {
|
public Boolean visitMarkInstruction(@NotNull MarkInstruction instruction) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Boolean visitMagic(MagicInstruction instruction) {
|
public Boolean visitMagic(@NotNull MagicInstruction instruction) {
|
||||||
return instruction.getSynthetic();
|
return instruction.getSynthetic();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
-64
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+44
@@ -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)
|
||||||
|
}
|
||||||
+38
@@ -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)"
|
||||||
|
}
|
||||||
-98
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+67
@@ -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)
|
||||||
|
}
|
||||||
@@ -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();
|
|
||||||
}
|
|
||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
-113
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+113
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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)
|
||||||
|
}
|
||||||
-42
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+28
@@ -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)
|
||||||
|
}
|
||||||
+4
-6
@@ -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.JetType;
|
||||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAdapter {
|
public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAdapter {
|
||||||
private JetControlFlowBuilder builder = null;
|
private JetControlFlowBuilder builder = null;
|
||||||
@@ -352,7 +349,7 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
|||||||
@Override
|
@Override
|
||||||
public void nondeterministicJump(@NotNull Label label, @NotNull JetElement element, @Nullable PseudoValue inputValue) {
|
public void nondeterministicJump(@NotNull Label label, @NotNull JetElement element, @Nullable PseudoValue inputValue) {
|
||||||
handleJumpInsideTryFinally(label);
|
handleJumpInsideTryFinally(label);
|
||||||
add(new NondeterministicJumpInstruction(element, label, getCurrentScope(), inputValue));
|
add(new NondeterministicJumpInstruction(element, Collections.singletonList(label), getCurrentScope(), inputValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -485,7 +482,8 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private PseudoValue read(@NotNull JetExpression expression, @Nullable PseudoValue receiverValue) {
|
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);
|
add(instruction);
|
||||||
return instruction.getOutputValue();
|
return instruction.getOutputValue();
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-7
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -14,12 +14,10 @@
|
|||||||
* limitations under the License.
|
* 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 {
|
public trait JetElementInstruction : Instruction {
|
||||||
@NotNull
|
public val element: JetElement
|
||||||
JetElement getElement();
|
|
||||||
}
|
}
|
||||||
-42
@@ -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+", " ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+28
@@ -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+", " ") ?: ""
|
||||||
|
}
|
||||||
+2
-3
@@ -14,7 +14,6 @@
|
|||||||
* limitations under the License.
|
* 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
|
||||||
}
|
|
||||||
-48
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+38
@@ -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)
|
||||||
|
}
|
||||||
-76
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+55
@@ -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)
|
||||||
|
}
|
||||||
@@ -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)})"
|
||||||
|
}
|
||||||
-131
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+85
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -41,6 +41,7 @@ public class PseudocodeImpl implements Pseudocode {
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
@@ -193,9 +194,9 @@ public class PseudocodeImpl implements Pseudocode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isDead(@NotNull Instruction instruction) {
|
private static boolean isDead(@NotNull Instruction instruction) {
|
||||||
if (!((InstructionImpl)instruction).isDead()) return false;
|
if (!((InstructionImpl)instruction).getDead()) return false;
|
||||||
for (Instruction copy : instruction.getCopies()) {
|
for (Instruction copy : instruction.getCopies()) {
|
||||||
if (!((InstructionImpl)copy).isDead()) return false;
|
if (!((InstructionImpl)copy).getDead()) return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -326,7 +327,7 @@ public class PseudocodeImpl implements Pseudocode {
|
|||||||
public void visitConditionalJump(ConditionalJumpInstruction instruction) {
|
public void visitConditionalJump(ConditionalJumpInstruction instruction) {
|
||||||
Instruction nextInstruction = getNextPosition(currentPosition);
|
Instruction nextInstruction = getNextPosition(currentPosition);
|
||||||
Instruction jumpTarget = getJumpTarget(instruction.getTargetLabel());
|
Instruction jumpTarget = getJumpTarget(instruction.getTargetLabel());
|
||||||
if (instruction.onTrue()) {
|
if (instruction.getOnTrue()) {
|
||||||
instruction.setNextOnFalse(nextInstruction);
|
instruction.setNextOnFalse(nextInstruction);
|
||||||
instruction.setNextOnTrue(jumpTarget);
|
instruction.setNextOnTrue(jumpTarget);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
-47
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+39
@@ -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)
|
||||||
|
}
|
||||||
-63
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
-54
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+37
@@ -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)
|
||||||
|
}
|
||||||
-75
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+50
@@ -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)
|
||||||
|
}
|
||||||
-65
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+41
@@ -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)
|
||||||
|
}
|
||||||
-64
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+46
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
-47
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+39
@@ -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)
|
||||||
|
}
|
||||||
-48
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+38
@@ -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)
|
||||||
|
}
|
||||||
-60
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+46
@@ -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)
|
||||||
|
}
|
||||||
-78
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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)
|
||||||
|
}
|
||||||
+21
-59
@@ -20,19 +20,19 @@ import org.jetbrains.jet.lang.psi.JetElement
|
|||||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall
|
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall
|
||||||
import kotlin.properties.Delegates
|
import kotlin.properties.Delegates
|
||||||
|
|
||||||
abstract class OperationInstruction protected(
|
public abstract class OperationInstruction protected(
|
||||||
element: JetElement,
|
element: JetElement,
|
||||||
lexicalScope: LexicalScope,
|
lexicalScope: LexicalScope,
|
||||||
val usedValues: List<PseudoValue>
|
public override val inputValues: List<PseudoValue>
|
||||||
) : InstructionWithNext(element, lexicalScope) {
|
) : InstructionWithNext(element, lexicalScope) {
|
||||||
protected var resultValue: PseudoValue? = null
|
protected var resultValue: PseudoValue? = null
|
||||||
|
|
||||||
override fun getInputValues(): List<PseudoValue> = usedValues
|
override val outputValue: PseudoValue?
|
||||||
override fun getOutputValue(): PseudoValue? = resultValue
|
get() = resultValue
|
||||||
|
|
||||||
protected fun renderInstruction(name: String, desc: String): String =
|
protected fun renderInstruction(name: String, desc: String): String =
|
||||||
"$name($desc" +
|
"$name($desc" +
|
||||||
(if (usedValues.notEmpty) "|${usedValues.makeString(", ")})" else ")") +
|
(if (inputValues.notEmpty) "|${inputValues.makeString(", ")})" else ")") +
|
||||||
(if (resultValue != null) " -> $resultValue" else "")
|
(if (resultValue != null) " -> $resultValue" else "")
|
||||||
|
|
||||||
protected fun setResult(value: PseudoValue?): OperationInstruction {
|
protected fun setResult(value: PseudoValue?): OperationInstruction {
|
||||||
@@ -45,22 +45,22 @@ abstract class OperationInstruction protected(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CallInstruction private(
|
public class CallInstruction private(
|
||||||
element: JetElement,
|
element: JetElement,
|
||||||
lexicalScope: LexicalScope,
|
lexicalScope: LexicalScope,
|
||||||
val resolvedCall: ResolvedCall<*>,
|
val resolvedCall: ResolvedCall<*>,
|
||||||
usedValues: List<PseudoValue>
|
inputValues: List<PseudoValue>
|
||||||
) : OperationInstruction(element, lexicalScope, usedValues) {
|
) : OperationInstruction(element, lexicalScope, inputValues) {
|
||||||
override fun accept(visitor: InstructionVisitor) {
|
override fun accept(visitor: InstructionVisitor) {
|
||||||
visitor.visitCallInstruction(this)
|
visitor.visitCallInstruction(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun <R> accept(visitor: InstructionVisitorWithResult<R>): R? {
|
override fun <R> accept(visitor: InstructionVisitorWithResult<R>): R {
|
||||||
return visitor.visitCallInstruction(this)
|
return visitor.visitCallInstruction(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createCopy() =
|
override fun createCopy() =
|
||||||
CallInstruction(element, lexicalScope, resolvedCall, usedValues).setResult(resultValue)
|
CallInstruction(element, lexicalScope, resolvedCall, inputValues).setResult(resultValue)
|
||||||
|
|
||||||
override fun toString() =
|
override fun toString() =
|
||||||
renderInstruction("call", "${render(element)}, ${resolvedCall.getResultingDescriptor()!!.getName()}")
|
renderInstruction("call", "${render(element)}, ${resolvedCall.getResultingDescriptor()!!.getName()}")
|
||||||
@@ -70,9 +70,9 @@ class CallInstruction private(
|
|||||||
element: JetElement,
|
element: JetElement,
|
||||||
lexicalScope: LexicalScope,
|
lexicalScope: LexicalScope,
|
||||||
resolvedCall: ResolvedCall<*>,
|
resolvedCall: ResolvedCall<*>,
|
||||||
usedValues: List<PseudoValue>,
|
inputValues: List<PseudoValue>,
|
||||||
factory: PseudoValueFactory?
|
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)
|
// 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
|
// "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.
|
// Examples: merging branches of 'if', 'when' and 'try' expressions, providing initial values for parameters, etc.
|
||||||
class MagicInstruction(
|
public class MagicInstruction(
|
||||||
element: JetElement,
|
element: JetElement,
|
||||||
lexicalScope: LexicalScope,
|
lexicalScope: LexicalScope,
|
||||||
val synthetic: Boolean,
|
val synthetic: Boolean,
|
||||||
usedValues: List<PseudoValue>
|
inputValues: List<PseudoValue>
|
||||||
) : OperationInstruction(element, lexicalScope, usedValues) {
|
) : OperationInstruction(element, lexicalScope, inputValues) {
|
||||||
override fun getOutputValue(): PseudoValue = resultValue!!
|
override val outputValue: PseudoValue
|
||||||
|
get() = resultValue!!
|
||||||
|
|
||||||
override fun accept(visitor: InstructionVisitor) {
|
override fun accept(visitor: InstructionVisitor) {
|
||||||
visitor.visitMagic(this)
|
visitor.visitMagic(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun <R> accept(visitor: InstructionVisitorWithResult<R>): R? {
|
override fun <R> accept(visitor: InstructionVisitorWithResult<R>): R {
|
||||||
return visitor.visitMagic(this)
|
return visitor.visitMagic(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createCopy() =
|
override fun createCopy() =
|
||||||
MagicInstruction(element, lexicalScope, synthetic, usedValues).setResult(resultValue)
|
MagicInstruction(element, lexicalScope, synthetic, inputValues).setResult(resultValue)
|
||||||
|
|
||||||
override fun toString() = renderInstruction("magic", render(element))
|
override fun toString() = renderInstruction("magic", render(element))
|
||||||
|
|
||||||
@@ -110,47 +111,8 @@ class MagicInstruction(
|
|||||||
valueElement: JetElement?,
|
valueElement: JetElement?,
|
||||||
lexicalScope: LexicalScope,
|
lexicalScope: LexicalScope,
|
||||||
synthetic: Boolean,
|
synthetic: Boolean,
|
||||||
usedValues: List<PseudoValue>,
|
inputValues: List<PseudoValue>,
|
||||||
factory: PseudoValueFactory
|
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)})"
|
|
||||||
}
|
|
||||||
@@ -21,7 +21,6 @@ import org.jetbrains.jet.lang.cfg.pseudocodeTraverser.traverseFollowingInstructi
|
|||||||
import java.util.HashSet
|
import java.util.HashSet
|
||||||
import org.jetbrains.jet.lang.cfg.pseudocodeTraverser.TraversalOrder
|
import org.jetbrains.jet.lang.cfg.pseudocodeTraverser.TraversalOrder
|
||||||
import org.jetbrains.jet.lang.psi.JetFunction
|
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.psiUtil.getParentByType
|
||||||
import org.jetbrains.jet.lang.psi.JetFunctionLiteral
|
import org.jetbrains.jet.lang.psi.JetFunctionLiteral
|
||||||
|
|
||||||
@@ -41,6 +40,6 @@ fun JetExpression.isStatement(pseudocode: Pseudocode): Boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val instruction = value.createdAt
|
val instruction = value.createdAt
|
||||||
if (considerUsedIfCreatedBeforeExit() && instruction.getNextInstructions().any { it == pseudocode.getExitInstruction() }) return false
|
if (considerUsedIfCreatedBeforeExit() && instruction.nextInstructions.any { it == pseudocode.getExitInstruction() }) return false
|
||||||
return traverseFollowingInstructions(instruction, HashSet(), TraversalOrder.FORWARD) { value !in it.getInputValues() }
|
return traverseFollowingInstructions(instruction, HashSet(), TraversalOrder.FORWARD) { value !in it.inputValues }
|
||||||
}
|
}
|
||||||
@@ -109,7 +109,7 @@ public abstract class AbstractControlFlowTest extends AbstractPseudocodeTest {
|
|||||||
//check edges directions
|
//check edges directions
|
||||||
Collection<Instruction> instructions = pseudocode.getAllInstructions();
|
Collection<Instruction> instructions = pseudocode.getAllInstructions();
|
||||||
for (Instruction instruction : instructions) {
|
for (Instruction instruction : instructions) {
|
||||||
if (!((InstructionImpl)instruction).isDead()) {
|
if (!((InstructionImpl)instruction).getDead()) {
|
||||||
for (Instruction nextInstruction : instruction.getNextInstructions()) {
|
for (Instruction nextInstruction : instruction.getNextInstructions()) {
|
||||||
assertTrue("instruction '" + instruction + "' has '" + nextInstruction + "' among next instructions list, but not vice versa",
|
assertTrue("instruction '" + instruction + "' has '" + nextInstruction + "' among next instructions list, but not vice versa",
|
||||||
nextInstruction.getPreviousInstructions().contains(instruction));
|
nextInstruction.getPreviousInstructions().contains(instruction));
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ public abstract class AbstractPseudoValueTest : AbstractPseudocodeTest() {
|
|||||||
fun elementText(element: JetElement): String = element.getText()!!.replaceAll("\\s+", " ")
|
fun elementText(element: JetElement): String = element.getText()!!.replaceAll("\\s+", " ")
|
||||||
|
|
||||||
fun valueDescription(element: JetElement, value: PseudoValue): String {
|
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)
|
val elementToValues = getElementToValueMap(pseudocode)
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ public abstract class AbstractPseudocodeTest extends KotlinTestWithEnvironment {
|
|||||||
@NotNull Set<Instruction> remainedAfterPostProcessInstructions
|
@NotNull Set<Instruction> remainedAfterPostProcessInstructions
|
||||||
) {
|
) {
|
||||||
boolean isRemovedThroughPostProcess = !remainedAfterPostProcessInstructions.contains(instruction);
|
boolean isRemovedThroughPostProcess = !remainedAfterPostProcessInstructions.contains(instruction);
|
||||||
assert isRemovedThroughPostProcess == ((InstructionImpl)instruction).isDead();
|
assert isRemovedThroughPostProcess == ((InstructionImpl)instruction).getDead();
|
||||||
return isRemovedThroughPostProcess ? "-" : " ";
|
return isRemovedThroughPostProcess ? "-" : " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+12
-12
@@ -70,27 +70,27 @@ private fun List<Instruction>.getModifiedVarDescriptors(bindingContext: BindingC
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun List<Instruction>.getExitPoints(): List<Instruction> =
|
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 {
|
private fun List<Instruction>.getResultType(bindingContext: BindingContext, options: ExtractionOptions): JetType {
|
||||||
fun instructionToType(instruction: Instruction): JetType? {
|
fun instructionToType(instruction: Instruction): JetType? {
|
||||||
val expression = when (instruction) {
|
val expression = when (instruction) {
|
||||||
is ReturnValueInstruction -> {
|
is ReturnValueInstruction -> {
|
||||||
(instruction.getElement() as JetReturnExpression).getReturnedExpression()
|
(instruction.element as JetReturnExpression).getReturnedExpression()
|
||||||
}
|
}
|
||||||
is CallInstruction -> {
|
is CallInstruction -> {
|
||||||
val callElement = instruction.resolvedCall.getCall().getCallElement() as? JetExpression
|
val callElement = instruction.resolvedCall.getCall().getCallElement() as? JetExpression
|
||||||
if (callElement is JetSimpleNameExpression) callElement.getParentByType(javaClass<JetExpression>(), true) else callElement
|
if (callElement is JetSimpleNameExpression) callElement.getParentByType(javaClass<JetExpression>(), true) else callElement
|
||||||
}
|
}
|
||||||
is ReadValueInstruction, is OperationInstruction -> {
|
is ReadValueInstruction, is OperationInstruction -> {
|
||||||
(instruction as JetElementInstruction).getElement() as? JetExpression
|
(instruction as JetElementInstruction).element as? JetExpression
|
||||||
}
|
}
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expression == null) return null
|
if (expression == null) return null
|
||||||
if (options.inferUnitTypeForUnusedValues) {
|
if (options.inferUnitTypeForUnusedValues) {
|
||||||
val pseudocode = firstOrNull()?.getOwner()
|
val pseudocode = firstOrNull()?.owner
|
||||||
if (pseudocode != null && expression.isStatement(pseudocode)) return null
|
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 {
|
private fun List<AbstractJumpInstruction>.checkEquivalence(checkPsi: Boolean): Boolean {
|
||||||
if (mapTo(HashSet<Label?>()) { it.getTargetLabel() }.size > 1) return false
|
if (mapTo(HashSet<Label?>()) { it.targetLabel }.size > 1) return false
|
||||||
return !checkPsi || mapTo(HashSet<String?>()) { it.getElement().getText() }.size <= 1
|
return !checkPsi || mapTo(HashSet<String?>()) { it.element.getText() }.size <= 1
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun JetType.isMeaningful(): Boolean {
|
private fun JetType.isMeaningful(): Boolean {
|
||||||
@@ -121,10 +121,10 @@ private fun List<Instruction>.analyzeControlFlow(
|
|||||||
val defaultExits = ArrayList<Instruction>()
|
val defaultExits = ArrayList<Instruction>()
|
||||||
val jumpExits = ArrayList<AbstractJumpInstruction>()
|
val jumpExits = ArrayList<AbstractJumpInstruction>()
|
||||||
exitPoints.forEach {
|
exitPoints.forEach {
|
||||||
val e = (it as? UnconditionalJumpInstruction)?.getElement()
|
val e = (it as? UnconditionalJumpInstruction)?.element
|
||||||
val insn =
|
val insn =
|
||||||
if (e != null && e !is JetBreakExpression && e !is JetContinueExpression) {
|
if (e != null && e !is JetBreakExpression && e !is JetContinueExpression) {
|
||||||
it.getPreviousInstructions().firstOrNull()
|
it.previousInstructions.firstOrNull()
|
||||||
}
|
}
|
||||||
else it
|
else it
|
||||||
|
|
||||||
@@ -132,7 +132,7 @@ private fun List<Instruction>.analyzeControlFlow(
|
|||||||
is ReturnValueInstruction -> valuedReturnExits.add(insn)
|
is ReturnValueInstruction -> valuedReturnExits.add(insn)
|
||||||
|
|
||||||
is AbstractJumpInstruction -> {
|
is AbstractJumpInstruction -> {
|
||||||
val element = insn.getElement()
|
val element = insn.element
|
||||||
if (element is JetReturnExpression
|
if (element is JetReturnExpression
|
||||||
|| element is JetBreakExpression
|
|| element is JetBreakExpression
|
||||||
|| element is JetContinueExpression) {
|
|| element is JetContinueExpression) {
|
||||||
@@ -187,7 +187,7 @@ private fun List<Instruction>.analyzeControlFlow(
|
|||||||
if (defaultExits.isNotEmpty()) {
|
if (defaultExits.isNotEmpty()) {
|
||||||
if (valuedReturnExits.size != 1) return multipleExitsError
|
if (valuedReturnExits.size != 1) return multipleExitsError
|
||||||
|
|
||||||
val element = valuedReturnExits.first!!.getElement()
|
val element = valuedReturnExits.first!!.element
|
||||||
return Pair(ConditionalJump(listOf(element), element), null)
|
return Pair(ConditionalJump(listOf(element), element), null)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,7 +198,7 @@ private fun List<Instruction>.analyzeControlFlow(
|
|||||||
if (jumpExits.isNotEmpty()) {
|
if (jumpExits.isNotEmpty()) {
|
||||||
if (!jumpExits.checkEquivalence(true)) return multipleExitsError
|
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)
|
if (defaultExits.isNotEmpty()) return Pair(ConditionalJump(elements, elements.first!!), null)
|
||||||
return Pair(UnconditionalJump(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 pseudocode = PseudocodeUtil.generatePseudocode(enclosingDeclaration, bindingContext)
|
||||||
val localInstructions = pseudocode.getInstructions().filter {
|
val localInstructions = pseudocode.getInstructions().filter {
|
||||||
it is JetElementInstruction && it.getElement().isInsideOf(originalElements)
|
it is JetElementInstruction && it.element.isInsideOf(originalElements)
|
||||||
}
|
}
|
||||||
|
|
||||||
val replacementMap = HashMap<Int, Replacement>()
|
val replacementMap = HashMap<Int, Replacement>()
|
||||||
|
|||||||
Reference in New Issue
Block a user