Added information about anonymous initializers to cfg & proper checks

This commit is contained in:
svtk
2011-11-01 18:54:33 +04:00
parent ecdceb4447
commit eab7fdf4bc
6 changed files with 109 additions and 9 deletions
@@ -781,6 +781,21 @@ public class JetControlFlowProcessor {
// TODO : Support Type Arguments. Class object may be initialized at this point");
}
@Override
public void visitAnonymousInitializer(JetClassInitializer classInitializer) {
classInitializer.getBody().accept(this);
}
@Override
public void visitClass(JetClass klass) {
List<JetDeclaration> declarations = klass.getDeclarations();
for (JetDeclaration declaration : declarations) {
if (declaration instanceof JetProperty || declaration instanceof JetClassInitializer) {
declaration.accept(this);
}
}
}
@Override
public void visitJetElement(JetElement element) {
builder.unsupported(element);
@@ -4,9 +4,7 @@ import com.google.common.collect.Lists;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.JetStandardClasses;
@@ -14,6 +12,7 @@ import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
import org.jetbrains.jet.lexer.JetTokens;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -38,6 +37,11 @@ public class ControlFlowAnalyzer {
}
public void process() {
for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) {
JetClass aClass = entry.getKey();
MutableClassDescriptor classDescriptor = entry.getValue();
checkClass(aClass, classDescriptor);
}
for (Map.Entry<JetNamedFunction, FunctionDescriptorImpl> entry : context.getFunctions().entrySet()) {
JetNamedFunction function = entry.getKey();
FunctionDescriptorImpl functionDescriptor = entry.getValue();
@@ -61,6 +65,11 @@ public class ControlFlowAnalyzer {
checkProperty(property);
}
}
private void checkClass(JetClass klass, MutableClassDescriptor classDescriptor) {
JetFlowInformationProvider flowInformationProvider = new JetFlowInformationProvider(klass, klass, flowDataTraceFactory, context.getTrace());
flowInformationProvider.markUninitializedVariables(klass, true);
}
private void checkFunction(JetDeclarationWithBody function, FunctionDescriptor functionDescriptor, final @NotNull JetType expectedReturnType) {
assert function instanceof JetDeclaration;
@@ -114,8 +123,7 @@ public class ControlFlowAnalyzer {
});
}
if (!declaredLocally) {
flowInformationProvider.markUninitializedVariables(function.asElement(), functionDescriptor.getValueParameters());
flowInformationProvider.markUninitializedVariables(function.asElement(), false);
if (((JetDeclaration) function).hasModifier(JetTokens.INLINE_KEYWORD)) {
//inline functions after M1
// flowInformationProvider.markNotOnlyInvokedFunctionVariables(function.asElement(), functionDescriptor.getValueParameters());
@@ -0,0 +1,41 @@
== AnonymousInitializers ==
class AnonymousInitializers() {
val k = 34
val i: Int
{
$i = 12
}
val j: Int
get() = 20
{
$i = 13
}
}
---------------------
l0:
<START> NEXT:[r(34)] PREV:[]
r(34) NEXT:[w(k)] PREV:[<START>]
w(k) NEXT:[r(12)] PREV:[r(34)]
r(12) NEXT:[w($i)] PREV:[w(k)]
w($i) NEXT:[r(13)] PREV:[r(12)]
r(13) NEXT:[w($i)] PREV:[w($i)]
w($i) NEXT:[<END>] PREV:[r(13)]
l1:
<END> NEXT:[] PREV:[w($i)]
error:
<ERROR> NEXT:[] PREV:[]
=====================
== k ==
val k = 34
---------------------
l0:
<START> NEXT:[r(34)] PREV:[]
r(34) NEXT:[<END>] PREV:[<START>]
l1:
<END> NEXT:[] PREV:[r(34)]
error:
<ERROR> NEXT:[] PREV:[]
=====================
@@ -0,0 +1,15 @@
class AnonymousInitializers() {
val k = 34
val i: Int
{
$i = 12
}
val j: Int
get() = 20
{
$i = 13
}
}
@@ -1,3 +1,15 @@
== Test ==
class Test {
var x : Int;
}
---------------------
l0:
<START> NEXT:[<END>] PREV:[]
l1:
<END> NEXT:[] PREV:[<START>]
error:
<ERROR> NEXT:[] PREV:[]
=====================
== assignments ==
fun assignments() : Unit {
var x = 1
@@ -32,7 +32,12 @@ public class JetControlFlowTest extends JetLiteFixture {
super(dataPath);
myName = name;
}
@Override
public String getName() {
return "test" + myName;
}
protected String getTestFilePath() {
return myFullDataPath + "/" + myName;
}
@@ -94,15 +99,19 @@ public class JetControlFlowTest extends JetLiteFixture {
int i = 0;
for (Pseudocode pseudocode : pseudocodes) {
JetElement correspondingElement = pseudocode.getCorrespondingElement();
String label;
assert correspondingElement instanceof JetNamedDeclaration;
String label = "";
assert (correspondingElement instanceof JetNamedDeclaration || correspondingElement instanceof JetConstructor) :
"Unexpected element class is pseudocode: " + correspondingElement.getClass();
if (correspondingElement instanceof JetFunctionLiteral) {
label = "anonymous_" + i++;
}
else {
else if (correspondingElement instanceof JetNamedDeclaration) {
JetNamedDeclaration namedDeclaration = (JetNamedDeclaration) correspondingElement;
label = namedDeclaration.getName();
}
else {
label = "this";
}
instructionDump.append("== ").append(label).append(" ==\n");