get rid of JetPseudocodeTrace

and JetControlFlowDataTraceFactory
This commit is contained in:
Svetlana Isakova
2012-05-26 12:46:10 +04:00
parent 09a91f2f92
commit 0bf65bfe1e
24 changed files with 118 additions and 282 deletions
@@ -34,7 +34,6 @@ import org.jetbrains.jet.codegen.*;
import org.jetbrains.jet.cli.common.messages.AnalyzerWithCompilerReport; import org.jetbrains.jet.cli.common.messages.AnalyzerWithCompilerReport;
import org.jetbrains.jet.cli.common.messages.CompilerMessageLocation; import org.jetbrains.jet.cli.common.messages.CompilerMessageLocation;
import org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity; import org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetPsiUtil; import org.jetbrains.jet.lang.psi.JetPsiUtil;
import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqName;
@@ -246,7 +245,6 @@ public class KotlinToJVMBytecodeCompiler {
public AnalyzeExhaust invoke() { public AnalyzeExhaust invoke() {
return AnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration( return AnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
environment.getProject(), environment.getSourceFiles(), filesToAnalyzeCompletely, environment.getProject(), environment.getSourceFiles(), filesToAnalyzeCompletely,
JetControlFlowDataTraceFactory.EMPTY,
configuration.getEnvironment().getCompilerDependencies()); configuration.getEnvironment().getCompilerDependencies());
} }
}, environment.getSourceFiles() }, environment.getSourceFiles()
@@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.cfg;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.cfg.pseudocode.Pseudocode;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import java.util.List; import java.util.List;
@@ -64,7 +65,7 @@ public interface JetControlFlowBuilder {
// Subroutines // Subroutines
void enterSubroutine(@NotNull JetDeclaration subroutine); void enterSubroutine(@NotNull JetDeclaration subroutine);
void exitSubroutine(@NotNull JetDeclaration subroutine); Pseudocode exitSubroutine(@NotNull JetDeclaration subroutine);
@NotNull @NotNull
JetElement getCurrentSubroutine(); JetElement getCurrentSubroutine();
@@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.cfg;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.cfg.pseudocode.Pseudocode;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import java.util.List; import java.util.List;
@@ -157,9 +158,9 @@ public class JetControlFlowBuilderAdapter implements JetControlFlowBuilder {
} }
@Override @Override
public void exitSubroutine(@NotNull JetDeclaration subroutine) { public Pseudocode exitSubroutine(@NotNull JetDeclaration subroutine) {
assert builder != null; assert builder != null;
builder.exitSubroutine(subroutine); return builder.exitSubroutine(subroutine);
} }
@NotNull @NotNull
@@ -21,6 +21,9 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.cfg.pseudocode.Pseudocode;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowInstructionsGenerator;
import org.jetbrains.jet.lang.cfg.pseudocode.PseudocodeImpl;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.BindingContextUtils;
@@ -45,12 +48,22 @@ public class JetControlFlowProcessor {
private final JetControlFlowBuilder builder; private final JetControlFlowBuilder builder;
private final BindingTrace trace; private final BindingTrace trace;
public JetControlFlowProcessor(BindingTrace trace, JetControlFlowBuilder builder) { public JetControlFlowProcessor(BindingTrace trace) {
this.builder = builder; this.builder = new JetControlFlowInstructionsGenerator();
this.trace = trace; this.trace = trace;
} }
public void generate(@NotNull JetDeclaration subroutine) { //todo
public Pseudocode generatePseudocode(@NotNull JetDeclaration subroutine) {
Pseudocode pseudocode = generate(subroutine);
((PseudocodeImpl)pseudocode).postProcess();
for (Pseudocode localPseudocode : pseudocode.getLocalDeclarations()) {
((PseudocodeImpl)localPseudocode).postProcess();
}
return pseudocode;
}
public Pseudocode generate(@NotNull JetDeclaration subroutine) {
builder.enterSubroutine(subroutine); builder.enterSubroutine(subroutine);
if (subroutine instanceof JetDeclarationWithBody) { if (subroutine instanceof JetDeclarationWithBody) {
JetDeclarationWithBody declarationWithBody = (JetDeclarationWithBody) subroutine; JetDeclarationWithBody declarationWithBody = (JetDeclarationWithBody) subroutine;
@@ -67,7 +80,7 @@ public class JetControlFlowProcessor {
else { else {
subroutine.accept(new CFPVisitor(false)); subroutine.accept(new CFPVisitor(false));
} }
builder.exitSubroutine(subroutine); return builder.exitSubroutine(subroutine);
} }
private void processLocalDeclaration(@NotNull JetDeclaration subroutine) { private void processLocalDeclaration(@NotNull JetDeclaration subroutine) {
@@ -17,7 +17,6 @@
package org.jetbrains.jet.lang.cfg; package org.jetbrains.jet.lang.cfg;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.IElementType;
@@ -33,12 +32,14 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.jet.plugin.JetMainDetector; import org.jetbrains.jet.plugin.JetMainDetector;
import java.util.*; import java.util.Collection;
import java.util.List;
import java.util.Set;
import static org.jetbrains.jet.lang.diagnostics.Errors.*; import static org.jetbrains.jet.lang.diagnostics.Errors.*;
import static org.jetbrains.jet.lang.resolve.BindingContext.CAPTURED_IN_CLOSURE; import static org.jetbrains.jet.lang.resolve.BindingContext.CAPTURED_IN_CLOSURE;
@@ -49,67 +50,22 @@ import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
*/ */
public class JetFlowInformationProvider { public class JetFlowInformationProvider {
private final Map<JetElement, Pseudocode> pseudocodeMap; private final JetDeclaration subroutine;
private final Map<JetElement, PseudocodeData> pseudocodeDataMap; private final Pseudocode pseudocode;
private final PseudocodeData pseudocodeData;
private BindingTrace trace; private BindingTrace trace;
public JetFlowInformationProvider(@NotNull JetDeclaration declaration, @NotNull final JetExpression bodyExpression, @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory, @NotNull BindingTrace trace) { public JetFlowInformationProvider(
@NotNull JetDeclaration declaration,
@NotNull BindingTrace trace) {
subroutine = declaration;
this.trace = trace; this.trace = trace;
final JetPseudocodeTrace pseudocodeTrace = flowDataTraceFactory.createTrace(declaration); pseudocode = new JetControlFlowProcessor(trace).generatePseudocode(declaration);
pseudocodeMap = new LinkedHashMap<JetElement, Pseudocode>(); pseudocodeData = new PseudocodeData(pseudocode, trace);
pseudocodeDataMap = new HashMap<JetElement, PseudocodeData>();
final Map<JetElement, Instruction> representativeInstructions = new HashMap<JetElement, Instruction>();
final Map<JetExpression, LoopInfo> loopInfo = Maps.newHashMap();
JetPseudocodeTrace wrappedTrace = new JetPseudocodeTrace() {
@Override
public void recordControlFlowData(@NotNull JetElement element, @NotNull Pseudocode pseudocode) {
pseudocodeTrace.recordControlFlowData(element, pseudocode);
pseudocodeMap.put(element, pseudocode);
}
@Override
public void recordRepresentativeInstruction(@NotNull JetElement element, @NotNull Instruction instruction) {
Instruction oldValue = representativeInstructions.put(element, instruction);
// assert oldValue == null : element.getText();
pseudocodeTrace.recordRepresentativeInstruction(element, instruction);
}
@Override
public void recordLoopInfo(JetExpression expression, LoopInfo blockInfo) {
loopInfo.put(expression, blockInfo);
pseudocodeTrace.recordLoopInfo(expression, blockInfo);
}
@Override
public void close() {
pseudocodeTrace.close();
List<Pseudocode> values = Lists.newArrayList(pseudocodeMap.values());
Collections.reverse(values);
for (Pseudocode pseudocode : values) {
pseudocode.postProcess();
}
}
};
JetControlFlowInstructionsGenerator instructionsGenerator = new JetControlFlowInstructionsGenerator(wrappedTrace);
new JetControlFlowProcessor(trace, instructionsGenerator).generate(declaration);
wrappedTrace.close();
} }
private PseudocodeData getPseudocodeData(@NotNull JetElement element) { private void collectReturnExpressions(@NotNull final Collection<JetElement> returnedExpressions) {
PseudocodeData pseudocodeData = pseudocodeDataMap.get(element);
if (pseudocodeData == null) {
Pseudocode pseudocode = pseudocodeMap.get(element);
assert pseudocode != null;
pseudocodeData = new PseudocodeData(pseudocode, trace);
pseudocodeDataMap.put(element, pseudocodeData);
}
return pseudocodeData;
}
private void collectReturnExpressions(@NotNull JetElement subroutine, @NotNull final Collection<JetElement> returnedExpressions) {
Pseudocode pseudocode = pseudocodeMap.get(subroutine);
assert pseudocode != null;
final Set<Instruction> instructions = Sets.newHashSet(pseudocode.getInstructions()); final Set<Instruction> instructions = Sets.newHashSet(pseudocode.getInstructions());
SubroutineExitInstruction exitInstruction = pseudocode.getExitInstruction(); SubroutineExitInstruction exitInstruction = pseudocode.getExitInstruction();
for (Instruction previousInstruction : exitInstruction.getPreviousInstructions()) { for (Instruction previousInstruction : exitInstruction.getPreviousInstructions()) {
@@ -164,14 +120,16 @@ public class JetFlowInformationProvider {
} }
} }
public void checkDefiniteReturn(@NotNull final JetDeclarationWithBody function, final @NotNull JetType expectedReturnType) { public void checkDefiniteReturn(final @NotNull JetType expectedReturnType) {
assert subroutine instanceof JetDeclarationWithBody;
JetDeclarationWithBody function = (JetDeclarationWithBody) subroutine;
assert function instanceof JetDeclaration; assert function instanceof JetDeclaration;
JetExpression bodyExpression = function.getBodyExpression(); JetExpression bodyExpression = function.getBodyExpression();
if (bodyExpression == null) return; if (bodyExpression == null) return;
List<JetElement> returnedExpressions = Lists.newArrayList(); List<JetElement> returnedExpressions = Lists.newArrayList();
collectReturnExpressions(function.asElement(), returnedExpressions); collectReturnExpressions(returnedExpressions);
boolean nothingReturned = returnedExpressions.isEmpty(); boolean nothingReturned = returnedExpressions.isEmpty();
@@ -211,9 +169,6 @@ public class JetFlowInformationProvider {
} }
private Set<JetElement> collectUnreachableCode(@NotNull JetElement subroutine) { private Set<JetElement> collectUnreachableCode(@NotNull JetElement subroutine) {
Pseudocode pseudocode = pseudocodeMap.get(subroutine);
assert pseudocode != null;
Collection<JetElement> unreachableElements = Lists.newArrayList(); Collection<JetElement> unreachableElements = Lists.newArrayList();
for (Instruction deadInstruction : pseudocode.getDeadInstructions()) { for (Instruction deadInstruction : pseudocode.getDeadInstructions()) {
if (deadInstruction instanceof JetElementInstruction && if (deadInstruction instanceof JetElementInstruction &&
@@ -228,12 +183,11 @@ public class JetFlowInformationProvider {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Uninitialized variables analysis // Uninitialized variables analysis
public void markUninitializedVariables(@NotNull JetElement subroutine, final boolean processLocalDeclaration) { public void markUninitializedVariables(final boolean processLocalDeclaration) {
final Collection<VariableDescriptor> varWithUninitializedErrorGenerated = Sets.newHashSet(); final Collection<VariableDescriptor> varWithUninitializedErrorGenerated = Sets.newHashSet();
final Collection<VariableDescriptor> varWithValReassignErrorGenerated = Sets.newHashSet(); final Collection<VariableDescriptor> varWithValReassignErrorGenerated = Sets.newHashSet();
final boolean processClassOrObject = subroutine instanceof JetClassOrObject; final boolean processClassOrObject = subroutine instanceof JetClassOrObject;
final PseudocodeData pseudocodeData = getPseudocodeData(subroutine);
pseudocodeData.traverseInstructionsGraph(true, true, new PseudocodeData.TraverseInstructionGraphStrategy() { pseudocodeData.traverseInstructionsGraph(true, true, new PseudocodeData.TraverseInstructionGraphStrategy() {
@Override @Override
public void execute(@NotNull Instruction instruction, @NotNull DeclarationData declarationData, @NotNull InstructionData instructionData) { public void execute(@NotNull Instruction instruction, @NotNull DeclarationData declarationData, @NotNull InstructionData instructionData) {
@@ -447,20 +401,10 @@ public class JetFlowInformationProvider {
} }
} }
private void analyzeLocalDeclarations(Pseudocode pseudocode, boolean processLocalDeclaration) {
for (Instruction instruction : pseudocode.getInstructions()) {
if (instruction instanceof LocalDeclarationInstruction) {
JetElement element = ((LocalDeclarationInstruction) instruction).getElement();
markUninitializedVariables(element, processLocalDeclaration);
}
}
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// "Unused variable" & "unused value" analyses // "Unused variable" & "unused value" analyses
public void markUnusedVariables(@NotNull JetElement subroutine) { public void markUnusedVariables() {
final PseudocodeData pseudocodeData = getPseudocodeData(subroutine);
pseudocodeData.traverseInstructionsGraph(true, false, new PseudocodeData.TraverseInstructionGraphStrategy() { pseudocodeData.traverseInstructionsGraph(true, false, new PseudocodeData.TraverseInstructionGraphStrategy() {
@Override @Override
public void execute(@NotNull Instruction instruction, @NotNull DeclarationData declarationData, @NotNull InstructionData instructionData) { public void execute(@NotNull Instruction instruction, @NotNull DeclarationData declarationData, @NotNull InstructionData instructionData) {
@@ -541,8 +485,7 @@ public class JetFlowInformationProvider {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// "Unused literals" in block // "Unused literals" in block
public void markUnusedLiteralsInBlock(@NotNull JetElement subroutine) { public void markUnusedLiteralsInBlock() {
Pseudocode pseudocode = pseudocodeMap.get(subroutine);
assert pseudocode != null; assert pseudocode != null;
JetControlFlowGraphTraverser<Void> traverser = JetControlFlowGraphTraverser.create(pseudocode, true, true); JetControlFlowGraphTraverser<Void> traverser = JetControlFlowGraphTraverser.create(pseudocode, true, true);
traverser.traverseAndAnalyzeInstructionGraph(new JetControlFlowGraphTraverser.InstructionDataAnalyzeStrategy<Void>() { traverser.traverseAndAnalyzeInstructionGraph(new JetControlFlowGraphTraverser.InstructionDataAnalyzeStrategy<Void>() {
@@ -1,36 +0,0 @@
/*
* Copyright 2010-2012 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;
/**
* @author abreslav
*/
public interface JetControlFlowDataTraceFactory {
JetControlFlowDataTraceFactory EMPTY = new JetControlFlowDataTraceFactory() {
@NotNull
@Override
public JetPseudocodeTrace createTrace(JetElement element) {
return JetPseudocodeTrace.EMPTY;
}
};
@NotNull
JetPseudocodeTrace createTrace(JetElement element);
}
@@ -35,12 +35,6 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
private final Stack<BlockInfo> allBlocks = new Stack<BlockInfo>(); private final Stack<BlockInfo> allBlocks = new Stack<BlockInfo>();
private final JetPseudocodeTrace trace;
public JetControlFlowInstructionsGenerator(JetPseudocodeTrace trace) {
this.trace = trace;
}
private void pushBuilder(JetElement scopingElement, JetElement subroutine) { private void pushBuilder(JetElement scopingElement, JetElement subroutine) {
JetControlFlowInstructionsGeneratorWorker worker = new JetControlFlowInstructionsGeneratorWorker(scopingElement, subroutine); JetControlFlowInstructionsGeneratorWorker worker = new JetControlFlowInstructionsGeneratorWorker(scopingElement, subroutine);
builders.push(worker); builders.push(worker);
@@ -49,7 +43,6 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
private JetControlFlowInstructionsGeneratorWorker popBuilder(@NotNull JetElement element) { private JetControlFlowInstructionsGeneratorWorker popBuilder(@NotNull JetElement element) {
JetControlFlowInstructionsGeneratorWorker worker = builders.pop(); JetControlFlowInstructionsGeneratorWorker worker = builders.pop();
trace.recordControlFlowData(element, worker.getPseudocode());
if (!builders.isEmpty()) { if (!builders.isEmpty()) {
builder = builders.peek(); builder = builders.peek();
} }
@@ -72,7 +65,7 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
} }
@Override @Override
public void exitSubroutine(@NotNull JetDeclaration subroutine) { public Pseudocode exitSubroutine(@NotNull JetDeclaration subroutine) {
super.exitSubroutine(subroutine); super.exitSubroutine(subroutine);
JetControlFlowInstructionsGeneratorWorker worker = popBuilder(subroutine); JetControlFlowInstructionsGeneratorWorker worker = popBuilder(subroutine);
if (!builders.empty()) { if (!builders.empty()) {
@@ -80,32 +73,29 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
LocalDeclarationInstruction instruction = new LocalDeclarationInstruction(subroutine, worker.getPseudocode()); LocalDeclarationInstruction instruction = new LocalDeclarationInstruction(subroutine, worker.getPseudocode());
builder.add(instruction); builder.add(instruction);
} }
return worker.getPseudocode();
} }
private class JetControlFlowInstructionsGeneratorWorker implements JetControlFlowBuilder { private class JetControlFlowInstructionsGeneratorWorker implements JetControlFlowBuilder {
private final Pseudocode pseudocode; private final PseudocodeImpl pseudocode;
private final Label error; private final Label error;
private final Label sink; private final Label sink;
private final JetElement returnSubroutine; private final JetElement returnSubroutine;
private JetControlFlowInstructionsGeneratorWorker(@NotNull JetElement scopingElement, @NotNull JetElement returnSubroutine) { private JetControlFlowInstructionsGeneratorWorker(@NotNull JetElement scopingElement, @NotNull JetElement returnSubroutine) {
this.pseudocode = new Pseudocode(scopingElement); this.pseudocode = new PseudocodeImpl(scopingElement);
this.error = pseudocode.createLabel("error"); this.error = pseudocode.createLabel("error");
this.sink = pseudocode.createLabel("sink"); this.sink = pseudocode.createLabel("sink");
this.returnSubroutine = returnSubroutine; this.returnSubroutine = returnSubroutine;
} }
public Pseudocode getPseudocode() { public PseudocodeImpl getPseudocode() {
return pseudocode; return pseudocode;
} }
private void add(@NotNull Instruction instruction) { private void add(@NotNull Instruction instruction) {
pseudocode.addInstruction(instruction); pseudocode.addInstruction(instruction);
if (instruction instanceof JetElementInstruction) {
JetElementInstruction elementInstruction = (JetElementInstruction) instruction;
trace.recordRepresentativeInstruction(elementInstruction.getElement(), instruction);
}
} }
@NotNull @NotNull
@@ -127,7 +117,7 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
loopInfo.push(blockInfo); loopInfo.push(blockInfo);
elementToBlockInfo.put(expression, blockInfo); elementToBlockInfo.put(expression, blockInfo);
allBlocks.push(blockInfo); allBlocks.push(blockInfo);
trace.recordLoopInfo(expression, blockInfo); pseudocode.recordLoopInfo(expression, blockInfo);
return blockInfo; return blockInfo;
} }
@@ -202,7 +192,7 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
} }
@Override @Override
public void exitSubroutine(@NotNull JetDeclaration subroutine) { public Pseudocode exitSubroutine(@NotNull JetDeclaration subroutine) {
bindLabel(getExitPoint(subroutine)); bindLabel(getExitPoint(subroutine));
pseudocode.addExitInstruction(new SubroutineExitInstruction(subroutine, "<END>")); pseudocode.addExitInstruction(new SubroutineExitInstruction(subroutine, "<END>"));
bindLabel(error); bindLabel(error);
@@ -211,6 +201,7 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
pseudocode.addSinkInstruction(new SubroutineSinkInstruction(subroutine, "<SINK>")); pseudocode.addSinkInstruction(new SubroutineSinkInstruction(subroutine, "<SINK>"));
elementToBlockInfo.remove(subroutine); elementToBlockInfo.remove(subroutine);
allBlocks.pop(); allBlocks.pop();
return null;
} }
@Override @Override
@@ -1,54 +0,0 @@
/*
* Copyright 2010-2012 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.LoopInfo;
import org.jetbrains.jet.lang.psi.JetElement;
import org.jetbrains.jet.lang.psi.JetExpression;
/**
* @author abreslav
*/
public interface JetPseudocodeTrace {
JetPseudocodeTrace EMPTY = new JetPseudocodeTrace() {
@Override
public void recordControlFlowData(@NotNull JetElement element, @NotNull Pseudocode pseudocode) {
}
@Override
public void recordRepresentativeInstruction(@NotNull JetElement element, @NotNull Instruction instruction) {
}
@Override
public void close() {
}
@Override
public void recordLoopInfo(JetExpression expression, LoopInfo blockInfo) {
}
};
void recordControlFlowData(@NotNull JetElement element, @NotNull Pseudocode pseudocode);
void recordRepresentativeInstruction(@NotNull JetElement element, @NotNull Instruction instruction);
void close();
void recordLoopInfo(JetExpression expression, LoopInfo blockInfo);
}
@@ -32,7 +32,7 @@ import java.util.*;
* @author abreslav * @author abreslav
* @author svtk * @author svtk
*/ */
public class PseudocodeImpl implements IPseudocode { public class PseudocodeImpl implements Pseudocode {
public class PseudocodeLabel implements Label { public class PseudocodeLabel implements Label {
private final String name; private final String name;
@@ -103,8 +103,8 @@ public class PseudocodeImpl implements IPseudocode {
@NotNull @NotNull
@Override @Override
public Set<IPseudocode> getLocalDeclarations() { public Set<Pseudocode> getLocalDeclarations() {
Set<IPseudocode> localDeclarations = Sets.newLinkedHashSet(); Set<Pseudocode> localDeclarations = Sets.newLinkedHashSet();
//todo look recursively inside local declarations //todo look recursively inside local declarations
for (Instruction instruction : instructions) { for (Instruction instruction : instructions) {
if (instruction instanceof LocalDeclarationInstruction) { if (instruction instanceof LocalDeclarationInstruction) {
@@ -16,22 +16,15 @@
package org.jetbrains.jet.lang.resolve; package org.jetbrains.jet.lang.resolve;
import com.google.common.base.Predicate;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor; import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.PsiErrorElement; import com.intellij.psi.PsiErrorElement;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.ModuleConfiguration;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.diagnostics.Diagnostic; import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.lang.diagnostics.DiagnosticHolder; import org.jetbrains.jet.lang.diagnostics.DiagnosticHolder;
import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils; import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
import org.jetbrains.jet.lang.psi.JetFile;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.List; import java.util.List;
/** /**
@@ -18,7 +18,6 @@ package org.jetbrains.jet.lang.resolve;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider; import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.descriptors.PropertyAccessorDescriptor; import org.jetbrains.jet.lang.descriptors.PropertyAccessorDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor; import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
@@ -37,7 +36,6 @@ import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
public class ControlFlowAnalyzer { public class ControlFlowAnalyzer {
private TopDownAnalysisParameters topDownAnalysisParameters; private TopDownAnalysisParameters topDownAnalysisParameters;
private BindingTrace trace; private BindingTrace trace;
private JetControlFlowDataTraceFactory flowDataTraceFactory;
@Inject @Inject
public void setTopDownAnalysisParameters(TopDownAnalysisParameters topDownAnalysisParameters) { public void setTopDownAnalysisParameters(TopDownAnalysisParameters topDownAnalysisParameters) {
@@ -49,11 +47,6 @@ public class ControlFlowAnalyzer {
this.trace = trace; this.trace = trace;
} }
@Inject
public void setFlowDataTraceFactory(JetControlFlowDataTraceFactory flowDataTraceFactory) {
this.flowDataTraceFactory = flowDataTraceFactory;
}
public void process(@NotNull BodiesResolveContext bodiesResolveContext) { public void process(@NotNull BodiesResolveContext bodiesResolveContext) {
for (JetClass aClass : bodiesResolveContext.getClasses().keySet()) { for (JetClass aClass : bodiesResolveContext.getClasses().keySet()) {
if (!bodiesResolveContext.completeAnalysisNeeded(aClass)) continue; if (!bodiesResolveContext.completeAnalysisNeeded(aClass)) continue;
@@ -86,8 +79,8 @@ public class ControlFlowAnalyzer {
private void checkClassOrObject(JetClassOrObject klass) { private void checkClassOrObject(JetClassOrObject klass) {
// A pseudocode of class initialization corresponds to a class // A pseudocode of class initialization corresponds to a class
JetFlowInformationProvider flowInformationProvider = new JetFlowInformationProvider((JetDeclaration) klass, (JetExpression) klass, flowDataTraceFactory, trace); JetFlowInformationProvider flowInformationProvider = new JetFlowInformationProvider((JetDeclaration) klass, trace);
flowInformationProvider.markUninitializedVariables((JetElement) klass, topDownAnalysisParameters.isDeclaredLocally()); flowInformationProvider.markUninitializedVariables(topDownAnalysisParameters.isDeclaredLocally());
} }
private void checkProperty(JetProperty property, PropertyDescriptor propertyDescriptor) { private void checkProperty(JetProperty property, PropertyDescriptor propertyDescriptor) {
@@ -105,16 +98,16 @@ public class ControlFlowAnalyzer {
JetExpression bodyExpression = function.getBodyExpression(); JetExpression bodyExpression = function.getBodyExpression();
if (bodyExpression == null) return; if (bodyExpression == null) return;
JetFlowInformationProvider flowInformationProvider = new JetFlowInformationProvider((JetDeclaration) function, bodyExpression, flowDataTraceFactory, trace); JetFlowInformationProvider flowInformationProvider = new JetFlowInformationProvider((JetDeclaration) function, trace);
flowInformationProvider.checkDefiniteReturn(function, expectedReturnType); flowInformationProvider.checkDefiniteReturn(expectedReturnType);
// Property accessor is checked through initialization of a class check (at 'checkClassOrObject') // Property accessor is checked through initialization of a class check (at 'checkClassOrObject')
boolean isPropertyAccessor = function instanceof JetPropertyAccessor; boolean isPropertyAccessor = function instanceof JetPropertyAccessor;
flowInformationProvider.markUninitializedVariables(function.asElement(), topDownAnalysisParameters.isDeclaredLocally() || isPropertyAccessor); flowInformationProvider.markUninitializedVariables(topDownAnalysisParameters.isDeclaredLocally() || isPropertyAccessor);
flowInformationProvider.markUnusedVariables(function.asElement()); flowInformationProvider.markUnusedVariables();
flowInformationProvider.markUnusedLiteralsInBlock(function.asElement()); flowInformationProvider.markUnusedLiteralsInBlock();
} }
} }
@@ -23,7 +23,6 @@ import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.di.InjectorForTopDownAnalyzerBasic; import org.jetbrains.jet.di.InjectorForTopDownAnalyzerBasic;
import org.jetbrains.jet.lang.ModuleConfiguration; import org.jetbrains.jet.lang.ModuleConfiguration;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.JetDeclaration; import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetFile;
@@ -188,7 +187,7 @@ public class TopDownAnalyzer {
TopDownAnalysisParameters topDownAnalysisParameters = new TopDownAnalysisParameters(Predicates.<PsiFile>alwaysFalse(), true, false); TopDownAnalysisParameters topDownAnalysisParameters = new TopDownAnalysisParameters(Predicates.<PsiFile>alwaysFalse(), true, false);
InjectorForTopDownAnalyzerBasic injector = new InjectorForTopDownAnalyzerBasic( InjectorForTopDownAnalyzerBasic injector = new InjectorForTopDownAnalyzerBasic(
project, topDownAnalysisParameters, new ObservableBindingTrace(trace), project, topDownAnalysisParameters, new ObservableBindingTrace(trace),
JetStandardClasses.FAKE_STANDARD_CLASSES_MODULE, null, ModuleConfiguration.EMPTY); JetStandardClasses.FAKE_STANDARD_CLASSES_MODULE, ModuleConfiguration.EMPTY);
injector.getTopDownAnalyzer().doProcessStandardLibraryNamespace(outerScope, standardLibraryNamespace, files); injector.getTopDownAnalyzer().doProcessStandardLibraryNamespace(outerScope, standardLibraryNamespace, files);
} }
@@ -220,7 +219,7 @@ public class TopDownAnalyzer {
InjectorForTopDownAnalyzerBasic injector = new InjectorForTopDownAnalyzerBasic( InjectorForTopDownAnalyzerBasic injector = new InjectorForTopDownAnalyzerBasic(
project, topDownAnalysisParameters, new ObservableBindingTrace(trace), moduleDescriptor, project, topDownAnalysisParameters, new ObservableBindingTrace(trace), moduleDescriptor,
JetControlFlowDataTraceFactory.EMPTY, ModuleConfiguration.EMPTY); ModuleConfiguration.EMPTY);
injector.getTopDownAnalyzer().doProcess(outerScope, new NamespaceLikeBuilder() { injector.getTopDownAnalyzer().doProcess(outerScope, new NamespaceLikeBuilder() {
@@ -33,7 +33,6 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.analyzer.AnalyzeExhaust; import org.jetbrains.jet.analyzer.AnalyzeExhaust;
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment; import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.diagnostics.UnresolvedReferenceDiagnosticFactory; import org.jetbrains.jet.lang.diagnostics.UnresolvedReferenceDiagnosticFactory;
import org.jetbrains.jet.lang.diagnostics.Diagnostic; import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.lang.diagnostics.Severity; import org.jetbrains.jet.lang.diagnostics.Severity;
@@ -170,8 +169,8 @@ public class JetTestUtils {
private JetTestUtils() { private JetTestUtils() {
} }
public static AnalyzeExhaust analyzeFile(@NotNull JetFile namespace, @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) { public static AnalyzeExhaust analyzeFile(@NotNull JetFile namespace) {
return AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegration(namespace, flowDataTraceFactory, return AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegration(namespace,
CompileCompilerDependenciesTest.compilerDependenciesForTests(CompilerSpecialMode.REGULAR, true)); CompileCompilerDependenciesTest.compilerDependenciesForTests(CompilerSpecialMode.REGULAR, true));
} }
@@ -28,10 +28,16 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.JetLiteFixture; import org.jetbrains.jet.JetLiteFixture;
import org.jetbrains.jet.JetTestCaseBuilder; import org.jetbrains.jet.JetTestCaseBuilder;
import org.jetbrains.jet.JetTestUtils; import org.jetbrains.jet.JetTestUtils;
import org.jetbrains.jet.lang.cfg.LoopInfo; import org.jetbrains.jet.analyzer.AnalyzeExhaust;
import org.jetbrains.jet.lang.cfg.JetControlFlowProcessor;
import org.jetbrains.jet.lang.cfg.pseudocode.*; import org.jetbrains.jet.lang.cfg.pseudocode.*;
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode; import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
import org.jetbrains.jet.util.slicedmap.ReadOnlySlice;
import org.jetbrains.jet.util.slicedmap.WritableSlice;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
@@ -72,37 +78,46 @@ public class JetControlFlowTest extends JetLiteFixture {
JetFile file = loadPsiFile(myName + ".jet"); JetFile file = loadPsiFile(myName + ".jet");
final Map<JetElement, Pseudocode> data = new LinkedHashMap<JetElement, Pseudocode>(); final Map<JetElement, Pseudocode> data = new LinkedHashMap<JetElement, Pseudocode>();
final JetPseudocodeTrace pseudocodeTrace = new JetPseudocodeTrace() { AnalyzeExhaust analyzeExhaust = JetTestUtils.analyzeFile(file);
List<JetDeclaration> declarations = file.getDeclarations();
final BindingContext bindingContext = analyzeExhaust.getBindingContext();
BindingTrace mockTrace = new BindingTrace() {
@Override @Override
public void recordControlFlowData(@NotNull JetElement element, @NotNull Pseudocode pseudocode) { public BindingContext getBindingContext() {
data.put(element, pseudocode); return bindingContext;
} }
@Override @Override
public void close() { public <K, V> void record(WritableSlice<K, V> slice, K key, V value) {
for (Pseudocode pseudocode : data.values()) {
pseudocode.postProcess();
}
} }
@Override @Override
public void recordLoopInfo(JetExpression expression, LoopInfo blockInfo) { public <K> void record(WritableSlice<K, Boolean> slice, K key) {
} }
@Override @Override
public void recordRepresentativeInstruction(@NotNull JetElement element, @NotNull Instruction instruction) { public <K, V> V get(ReadOnlySlice<K, V> slice, K key) {
return bindingContext.get(slice, key);
} }
};
JetTestUtils.analyzeFile(file, new JetControlFlowDataTraceFactory() {
@NotNull @NotNull
@Override @Override
public JetPseudocodeTrace createTrace(JetElement element) { public <K, V> Collection<K> getKeys(WritableSlice<K, V> slice) {
return pseudocodeTrace; return bindingContext.getKeys(slice);
} }
});
@Override
public void report(@NotNull Diagnostic diagnostic) {
}
};
for (JetDeclaration declaration : declarations) {
Pseudocode pseudocode = new JetControlFlowProcessor(mockTrace).generatePseudocode(declaration);
data.put(declaration, pseudocode);
for (Pseudocode localPseudocode : pseudocode.getLocalDeclarations()) {
data.put(localPseudocode.getCorrespondingElement(), localPseudocode);
}
}
try { try {
processCFData(myName, data); processCFData(myName, data);
@@ -123,6 +138,7 @@ public class JetControlFlowTest extends JetLiteFixture {
StringBuilder instructionDump = new StringBuilder(); StringBuilder instructionDump = new StringBuilder();
int i = 0; int i = 0;
for (Pseudocode pseudocode : pseudocodes) { for (Pseudocode pseudocode : pseudocodes) {
JetElement correspondingElement = pseudocode.getCorrespondingElement(); JetElement correspondingElement = pseudocode.getCorrespondingElement();
String label = ""; String label = "";
assert (correspondingElement instanceof JetNamedDeclaration || correspondingElement instanceof JetSecondaryConstructor || correspondingElement instanceof JetPropertyAccessor) : assert (correspondingElement instanceof JetNamedDeclaration || correspondingElement instanceof JetSecondaryConstructor || correspondingElement instanceof JetPropertyAccessor) :
@@ -146,11 +162,11 @@ public class JetControlFlowTest extends JetLiteFixture {
instructionDump.append(correspondingElement.getText()); instructionDump.append(correspondingElement.getText());
instructionDump.append("\n---------------------\n"); instructionDump.append("\n---------------------\n");
dumpInstructions(pseudocode, instructionDump); dumpInstructions((PseudocodeImpl) pseudocode, instructionDump);
instructionDump.append("=====================\n"); instructionDump.append("=====================\n");
//check edges directions //check edges directions
Collection<Instruction> instructions = pseudocode.getMutableInstructionList(); Collection<Instruction> instructions = ((PseudocodeImpl)pseudocode).getMutableInstructionList();
for (Instruction instruction : instructions) { for (Instruction instruction : instructions) {
if (!((InstructionImpl)instruction).isDead()) { if (!((InstructionImpl)instruction).isDead()) {
for (Instruction nextInstruction : instruction.getNextInstructions()) { for (Instruction nextInstruction : instruction.getNextInstructions()) {
@@ -181,7 +197,7 @@ public class JetControlFlowTest extends JetLiteFixture {
// } // }
} }
public void dfsDump(Pseudocode pseudocode, StringBuilder nodes, StringBuilder edges, Map<Instruction, String> nodeNames) { public void dfsDump(PseudocodeImpl pseudocode, StringBuilder nodes, StringBuilder edges, Map<Instruction, String> nodeNames) {
dfsDump(nodes, edges, pseudocode.getMutableInstructionList().get(0), nodeNames); dfsDump(nodes, edges, pseudocode.getMutableInstructionList().get(0), nodeNames);
} }
@@ -243,11 +259,11 @@ public class JetControlFlowTest extends JetLiteFixture {
return sb.toString(); return sb.toString();
} }
public void dumpInstructions(Pseudocode pseudocode, @NotNull StringBuilder out) { public void dumpInstructions(PseudocodeImpl pseudocode, @NotNull StringBuilder out) {
List<Instruction> instructions = pseudocode.getMutableInstructionList(); List<Instruction> instructions = pseudocode.getMutableInstructionList();
Set<Instruction> remainedAfterPostProcessInstructions = Sets.newHashSet(pseudocode.getInstructions()); Set<Instruction> remainedAfterPostProcessInstructions = Sets.newHashSet(pseudocode.getInstructions());
List<Pseudocode.PseudocodeLabel> labels = pseudocode.getLabels(); List<PseudocodeImpl.PseudocodeLabel> labels = pseudocode.getLabels();
List<Pseudocode> locals = new ArrayList<Pseudocode>(); List<PseudocodeImpl> locals = new ArrayList<PseudocodeImpl>();
int maxLength = 0; int maxLength = 0;
int maxNextLength = 0; int maxNextLength = 0;
for (Instruction instruction : instructions) { for (Instruction instruction : instructions) {
@@ -276,9 +292,9 @@ public class JetControlFlowTest extends JetLiteFixture {
Instruction instruction = instructions.get(i); Instruction instruction = instructions.get(i);
if (instruction instanceof LocalDeclarationInstruction) { if (instruction instanceof LocalDeclarationInstruction) {
LocalDeclarationInstruction localDeclarationInstruction = (LocalDeclarationInstruction) instruction; LocalDeclarationInstruction localDeclarationInstruction = (LocalDeclarationInstruction) instruction;
locals.add(localDeclarationInstruction.getBody()); locals.add((PseudocodeImpl) localDeclarationInstruction.getBody());
} }
for (Pseudocode.PseudocodeLabel label: labels) { for (PseudocodeImpl.PseudocodeLabel label: labels) {
if (label.getTargetInstructionIndex() == i) { if (label.getTargetInstructionIndex() == i) {
out.append(label.getName()).append(":\n"); out.append(label.getName()).append(":\n");
} }
@@ -288,7 +304,7 @@ public class JetControlFlowTest extends JetLiteFixture {
append(" NEXT:").append(String.format("%1$-" + maxNextLength + "s", formatInstructionList(instruction.getNextInstructions()))). append(" NEXT:").append(String.format("%1$-" + maxNextLength + "s", formatInstructionList(instruction.getNextInstructions()))).
append(" PREV:").append(formatInstructionList(instruction.getPreviousInstructions())).append("\n"); append(" PREV:").append(formatInstructionList(instruction.getPreviousInstructions())).append("\n");
} }
for (Pseudocode local : locals) { for (PseudocodeImpl local : locals) {
dumpInstructions(local, out); dumpInstructions(local, out);
} }
} }
@@ -300,7 +316,7 @@ public class JetControlFlowTest extends JetLiteFixture {
public void visitLocalDeclarationInstruction(LocalDeclarationInstruction instruction) { public void visitLocalDeclarationInstruction(LocalDeclarationInstruction instruction) {
int index = count[0]; int index = count[0];
// instruction.getBody().dumpSubgraph(out, "subgraph cluster_" + index, count, "color=blue;\nlabel = \"f" + index + "\";", nodeToName); // instruction.getBody().dumpSubgraph(out, "subgraph cluster_" + index, count, "color=blue;\nlabel = \"f" + index + "\";", nodeToName);
printEdge(out, nodeToName.get(instruction), nodeToName.get(instruction.getBody().getMutableInstructionList().get(0)), null); printEdge(out, nodeToName.get(instruction), nodeToName.get(((PseudocodeImpl)instruction.getBody()).getMutableInstructionList().get(0)), null);
visitInstructionWithNext(instruction); visitInstructionWithNext(instruction);
} }
@@ -415,7 +431,7 @@ public class JetControlFlowTest extends JetLiteFixture {
int[] count = new int[1]; int[] count = new int[1];
Map<Instruction, String> nodeToName = new HashMap<Instruction, String>(); Map<Instruction, String> nodeToName = new HashMap<Instruction, String>();
for (Pseudocode pseudocode : pseudocodes) { for (Pseudocode pseudocode : pseudocodes) {
dumpNodes(pseudocode.getMutableInstructionList(), out, count, nodeToName, Sets.newHashSet(pseudocode.getInstructions())); dumpNodes(((PseudocodeImpl)pseudocode).getMutableInstructionList(), out, count, nodeToName, Sets.newHashSet(pseudocode.getInstructions()));
} }
int i = 0; int i = 0;
for (Pseudocode pseudocode : pseudocodes) { for (Pseudocode pseudocode : pseudocodes) {
@@ -431,7 +447,7 @@ public class JetControlFlowTest extends JetLiteFixture {
out.println("subgraph cluster_" + i + " {\n" + out.println("subgraph cluster_" + i + " {\n" +
"label=\"" + label + "\";\n" + "label=\"" + label + "\";\n" +
"color=blue;\n"); "color=blue;\n");
dumpEdges(pseudocode.getMutableInstructionList(), out, count, nodeToName); dumpEdges(((PseudocodeImpl)pseudocode).getMutableInstructionList(), out, count, nodeToName);
out.println("}"); out.println("}");
i++; i++;
} }
@@ -21,7 +21,6 @@ import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.CompileCompilerDependenciesTest; import org.jetbrains.jet.CompileCompilerDependenciesTest;
import org.jetbrains.jet.JetLiteFixture; import org.jetbrains.jet.JetLiteFixture;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.diagnostics.Diagnostic; import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
@@ -107,8 +106,7 @@ public class CheckerTestUtilTest extends JetLiteFixture {
public void test(final @NotNull PsiFile psiFile) { public void test(final @NotNull PsiFile psiFile) {
BindingContext bindingContext = AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegration( BindingContext bindingContext = AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegration(
(JetFile) psiFile, JetControlFlowDataTraceFactory.EMPTY, (JetFile) psiFile, CompileCompilerDependenciesTest.compilerDependenciesForTests(CompilerSpecialMode.REGULAR, true))
CompileCompilerDependenciesTest.compilerDependenciesForTests(CompilerSpecialMode.REGULAR, true))
.getBindingContext(); .getBindingContext();
String expectedText = CheckerTestUtil.addDiagnosticMarkersToText(psiFile, CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, psiFile)).toString(); String expectedText = CheckerTestUtil.addDiagnosticMarkersToText(psiFile, CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, psiFile)).toString();
@@ -29,7 +29,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.JetLiteFixture; import org.jetbrains.jet.JetLiteFixture;
import org.jetbrains.jet.JetTestCaseBuilder; import org.jetbrains.jet.JetTestCaseBuilder;
import org.jetbrains.jet.JetTestUtils; import org.jetbrains.jet.JetTestUtils;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils; import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.AnalyzingUtils; import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
@@ -172,9 +171,7 @@ public class JetDiagnosticsTest extends JetLiteFixture {
} }
BindingContext bindingContext = AnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration( BindingContext bindingContext = AnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
getProject(), jetFiles, Predicates.<PsiFile>alwaysTrue(), JetControlFlowDataTraceFactory.EMPTY, getProject(), jetFiles, Predicates.<PsiFile>alwaysTrue(), myEnvironment.getCompilerDependencies()).getBindingContext();
myEnvironment.getCompilerDependencies())
.getBindingContext();
boolean ok = true; boolean ok = true;
@@ -26,7 +26,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.JetTestCaseBuilder; import org.jetbrains.jet.JetTestCaseBuilder;
import org.jetbrains.jet.JetTestUtils; import org.jetbrains.jet.JetTestUtils;
import org.jetbrains.jet.di.InjectorForJavaSemanticServices; import org.jetbrains.jet.di.InjectorForJavaSemanticServices;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
@@ -87,8 +86,7 @@ public class ReadJavaBinaryClassTest extends TestCaseWithTmpdir {
JetFile psiFile = (JetFile) ((PsiFileFactoryImpl) PsiFileFactory.getInstance(jetCoreEnvironment.getProject())).trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false); JetFile psiFile = (JetFile) ((PsiFileFactoryImpl) PsiFileFactory.getInstance(jetCoreEnvironment.getProject())).trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false);
BindingContext bindingContext = AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegrationAndCheckForErrors( BindingContext bindingContext = AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegrationAndCheckForErrors(
psiFile, JetControlFlowDataTraceFactory.EMPTY, psiFile, jetCoreEnvironment.getCompilerDependencies())
jetCoreEnvironment.getCompilerDependencies())
.getBindingContext(); .getBindingContext();
return bindingContext.get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, FqName.topLevel(Name.identifier("test"))); return bindingContext.get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, FqName.topLevel(Name.identifier("test")));
} }
@@ -24,7 +24,6 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.JetTestUtils; import org.jetbrains.jet.JetTestUtils;
import org.jetbrains.jet.analyzer.AnalyzeExhaust; import org.jetbrains.jet.analyzer.AnalyzeExhaust;
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment; import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetPsiUtil; import org.jetbrains.jet.lang.psi.JetPsiUtil;
import org.jetbrains.jet.lang.resolve.AnalyzingUtils; import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
@@ -186,8 +185,7 @@ public abstract class CodegenTestCase extends UsefulTestCase {
private GenerationState generateCommon(ClassBuilderFactory classBuilderFactory) { private GenerationState generateCommon(ClassBuilderFactory classBuilderFactory) {
final AnalyzeExhaust analyzeExhaust = AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegrationAndCheckForErrors( final AnalyzeExhaust analyzeExhaust = AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegrationAndCheckForErrors(
myFile, JetControlFlowDataTraceFactory.EMPTY, myFile, myEnvironment.getCompilerDependencies());
myEnvironment.getCompilerDependencies());
analyzeExhaust.throwIfError(); analyzeExhaust.throwIfError();
AnalyzingUtils.throwExceptionOnErrors(analyzeExhaust.getBindingContext()); AnalyzingUtils.throwExceptionOnErrors(analyzeExhaust.getBindingContext());
GenerationState state = new GenerationState(myEnvironment.getProject(), classBuilderFactory, analyzeExhaust, Collections.singletonList(myFile)); GenerationState state = new GenerationState(myEnvironment.getProject(), classBuilderFactory, analyzeExhaust, Collections.singletonList(myFile));
@@ -19,7 +19,6 @@ package org.jetbrains.jet.codegen;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.CompileCompilerDependenciesTest; import org.jetbrains.jet.CompileCompilerDependenciesTest;
import org.jetbrains.jet.analyzer.AnalyzeExhaust; import org.jetbrains.jet.analyzer.AnalyzeExhaust;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM; import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM;
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode; import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
@@ -37,8 +36,7 @@ public class GenerationUtils {
public static GenerationState compileFileGetGenerationStateForTest(JetFile psiFile, @NotNull CompilerSpecialMode compilerSpecialMode) { public static GenerationState compileFileGetGenerationStateForTest(JetFile psiFile, @NotNull CompilerSpecialMode compilerSpecialMode) {
final AnalyzeExhaust analyzeExhaust = AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegrationAndCheckForErrors( final AnalyzeExhaust analyzeExhaust = AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegrationAndCheckForErrors(
psiFile, JetControlFlowDataTraceFactory.EMPTY, psiFile, CompileCompilerDependenciesTest.compilerDependenciesForTests(compilerSpecialMode, true));
CompileCompilerDependenciesTest.compilerDependenciesForTests(compilerSpecialMode, true));
analyzeExhaust.throwIfError(); analyzeExhaust.throwIfError();
GenerationState state = new GenerationState(psiFile.getProject(), ClassBuilderFactories.binaries(false), analyzeExhaust, Collections.singletonList(psiFile)); GenerationState state = new GenerationState(psiFile.getProject(), ClassBuilderFactories.binaries(false), analyzeExhaust, Collections.singletonList(psiFile));
state.compileCorrectFiles(CompilationErrorHandler.THROW_EXCEPTION); state.compileCorrectFiles(CompilationErrorHandler.THROW_EXCEPTION);
@@ -22,7 +22,6 @@ import org.jetbrains.jet.JetLiteFixture;
import org.jetbrains.jet.JetTestCaseBuilder; import org.jetbrains.jet.JetTestCaseBuilder;
import org.jetbrains.jet.JetTestUtils; import org.jetbrains.jet.JetTestUtils;
import org.jetbrains.jet.analyzer.AnalyzeExhaust; import org.jetbrains.jet.analyzer.AnalyzeExhaust;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.psi.JetElement; import org.jetbrains.jet.lang.psi.JetElement;
import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetFile;
@@ -78,8 +77,7 @@ public class DescriptorRendererTest extends JetLiteFixture {
JetFile psiFile = createPsiFile(null, fileName, loadFile(fileName)); JetFile psiFile = createPsiFile(null, fileName, loadFile(fileName));
AnalyzeExhaust analyzeExhaust = AnalyzeExhaust analyzeExhaust =
AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegration( AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegration(
(JetFile) psiFile, JetControlFlowDataTraceFactory.EMPTY, (JetFile) psiFile, myEnvironment.getCompilerDependencies());
myEnvironment.getCompilerDependencies());
final BindingContext bindingContext = analyzeExhaust.getBindingContext(); final BindingContext bindingContext = analyzeExhaust.getBindingContext();
final List<DeclarationDescriptor> descriptors = new ArrayList<DeclarationDescriptor>(); final List<DeclarationDescriptor> descriptors = new ArrayList<DeclarationDescriptor>();
psiFile.acceptChildren(new JetVisitorVoid() { psiFile.acceptChildren(new JetVisitorVoid() {
@@ -27,7 +27,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.analyzer.AnalyzeExhaust; import org.jetbrains.jet.analyzer.AnalyzeExhaust;
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment; import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor; import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
@@ -154,8 +153,7 @@ public abstract class ExpectedResolveData {
JetStandardLibrary lib = JetStandardLibrary.getInstance(); JetStandardLibrary lib = JetStandardLibrary.getInstance();
AnalyzeExhaust analyzeExhaust = AnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(project, files, AnalyzeExhaust analyzeExhaust = AnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(project, files,
Predicates.<PsiFile>alwaysTrue(), JetControlFlowDataTraceFactory.EMPTY, Predicates.<PsiFile>alwaysTrue(), jetCoreEnvironment.getCompilerDependencies());
jetCoreEnvironment.getCompilerDependencies());
BindingContext bindingContext = analyzeExhaust.getBindingContext(); BindingContext bindingContext = analyzeExhaust.getBindingContext();
for (Diagnostic diagnostic : bindingContext.getDiagnostics()) { for (Diagnostic diagnostic : bindingContext.getDiagnostics()) {
if (diagnostic.getFactory() instanceof UnresolvedReferenceDiagnosticFactory) { if (diagnostic.getFactory() instanceof UnresolvedReferenceDiagnosticFactory) {
@@ -20,7 +20,6 @@ import org.jetbrains.jet.JetLiteFixture;
import org.jetbrains.jet.JetTestUtils; import org.jetbrains.jet.JetTestUtils;
import org.jetbrains.jet.analyzer.AnalyzeExhaust; import org.jetbrains.jet.analyzer.AnalyzeExhaust;
import org.jetbrains.jet.di.InjectorForTests; import org.jetbrains.jet.di.InjectorForTests;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
@@ -66,7 +65,6 @@ public class JetDefaultModalityModifiersTest extends JetLiteFixture {
JetDeclaration aClass = declarations.get(0); JetDeclaration aClass = declarations.get(0);
assert aClass instanceof JetClass; assert aClass instanceof JetClass;
AnalyzeExhaust bindingContext = AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegration(file, AnalyzeExhaust bindingContext = AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegration(file,
JetControlFlowDataTraceFactory.EMPTY,
myEnvironment.getCompilerDependencies()); myEnvironment.getCompilerDependencies());
DeclarationDescriptor classDescriptor = bindingContext.getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, aClass); DeclarationDescriptor classDescriptor = bindingContext.getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, aClass);
WritableScopeImpl scope = new WritableScopeImpl(libraryScope, root, RedeclarationHandler.DO_NOTHING); WritableScopeImpl scope = new WritableScopeImpl(libraryScope, root, RedeclarationHandler.DO_NOTHING);
@@ -33,7 +33,6 @@ import com.intellij.psi.util.PsiTreeUtil;
import jet.Tuple2; import jet.Tuple2;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
@@ -74,8 +73,7 @@ public class JetSourceNavigationHelper {
BindingContext bindingContext = AnalyzerFacadeProvider.getAnalyzerFacadeForProject(project).analyzeFiles( BindingContext bindingContext = AnalyzerFacadeProvider.getAnalyzerFacadeForProject(project).analyzeFiles(
project, project,
libraryFiles, libraryFiles,
Predicates.<PsiFile>alwaysTrue(), Predicates.<PsiFile>alwaysTrue()).getBindingContext();
JetControlFlowDataTraceFactory.EMPTY).getBindingContext();
D descriptor = bindingContext.get(slice, fqName); D descriptor = bindingContext.get(slice, fqName);
if (descriptor != null) { if (descriptor != null) {
return new Tuple2<BindingContext, D>(bindingContext, descriptor); return new Tuple2<BindingContext, D>(bindingContext, descriptor);
@@ -26,7 +26,6 @@ import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.codegen.ScriptCodegen; import org.jetbrains.jet.codegen.ScriptCodegen;
import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethods; import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethods;
import org.jetbrains.jet.lang.ModuleConfiguration; import org.jetbrains.jet.lang.ModuleConfiguration;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor; import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.*; import org.jetbrains.jet.lang.resolve.*;
@@ -93,7 +92,6 @@ public class AllInjectorsGenerator {
generator.addPublicParameter(TopDownAnalysisParameters.class); generator.addPublicParameter(TopDownAnalysisParameters.class);
generator.addPublicParameter(ObservableBindingTrace.class); generator.addPublicParameter(ObservableBindingTrace.class);
generator.addParameter(ModuleDescriptor.class); generator.addParameter(ModuleDescriptor.class);
generator.addParameter(JetControlFlowDataTraceFactory.class, false);
} }
private static void generateMacroInjector() throws IOException { private static void generateMacroInjector() throws IOException {