Added information about anonymous initializers to cfg & proper checks
This commit is contained in:
@@ -781,6 +781,21 @@ public class JetControlFlowProcessor {
|
|||||||
// TODO : Support Type Arguments. Class object may be initialized at this point");
|
// 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
|
@Override
|
||||||
public void visitJetElement(JetElement element) {
|
public void visitJetElement(JetElement element) {
|
||||||
builder.unsupported(element);
|
builder.unsupported(element);
|
||||||
|
|||||||
@@ -4,9 +4,7 @@ import com.google.common.collect.Lists;
|
|||||||
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.cfg.pseudocode.JetControlFlowDataTraceFactory;
|
||||||
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptorImpl;
|
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||||
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
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.lang.types.expressions.ExpressionTypingServices;
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
import org.jetbrains.jet.lexer.JetTokens;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -38,6 +37,11 @@ public class ControlFlowAnalyzer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void process() {
|
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()) {
|
for (Map.Entry<JetNamedFunction, FunctionDescriptorImpl> entry : context.getFunctions().entrySet()) {
|
||||||
JetNamedFunction function = entry.getKey();
|
JetNamedFunction function = entry.getKey();
|
||||||
FunctionDescriptorImpl functionDescriptor = entry.getValue();
|
FunctionDescriptorImpl functionDescriptor = entry.getValue();
|
||||||
@@ -62,6 +66,11 @@ public class ControlFlowAnalyzer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
private void checkFunction(JetDeclarationWithBody function, FunctionDescriptor functionDescriptor, final @NotNull JetType expectedReturnType) {
|
||||||
assert function instanceof JetDeclaration;
|
assert function instanceof JetDeclaration;
|
||||||
|
|
||||||
@@ -114,8 +123,7 @@ public class ControlFlowAnalyzer {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (!declaredLocally) {
|
if (!declaredLocally) {
|
||||||
flowInformationProvider.markUninitializedVariables(function.asElement(), functionDescriptor.getValueParameters());
|
flowInformationProvider.markUninitializedVariables(function.asElement(), false);
|
||||||
|
|
||||||
if (((JetDeclaration) function).hasModifier(JetTokens.INLINE_KEYWORD)) {
|
if (((JetDeclaration) function).hasModifier(JetTokens.INLINE_KEYWORD)) {
|
||||||
//inline functions after M1
|
//inline functions after M1
|
||||||
// flowInformationProvider.markNotOnlyInvokedFunctionVariables(function.asElement(), functionDescriptor.getValueParameters());
|
// 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 ==
|
== assignments ==
|
||||||
fun assignments() : Unit {
|
fun assignments() : Unit {
|
||||||
var x = 1
|
var x = 1
|
||||||
|
|||||||
@@ -33,6 +33,11 @@ public class JetControlFlowTest extends JetLiteFixture {
|
|||||||
myName = name;
|
myName = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "test" + myName;
|
||||||
|
}
|
||||||
|
|
||||||
protected String getTestFilePath() {
|
protected String getTestFilePath() {
|
||||||
return myFullDataPath + "/" + myName;
|
return myFullDataPath + "/" + myName;
|
||||||
}
|
}
|
||||||
@@ -94,15 +99,19 @@ public class JetControlFlowTest extends JetLiteFixture {
|
|||||||
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;
|
assert (correspondingElement instanceof JetNamedDeclaration || correspondingElement instanceof JetConstructor) :
|
||||||
|
"Unexpected element class is pseudocode: " + correspondingElement.getClass();
|
||||||
if (correspondingElement instanceof JetFunctionLiteral) {
|
if (correspondingElement instanceof JetFunctionLiteral) {
|
||||||
label = "anonymous_" + i++;
|
label = "anonymous_" + i++;
|
||||||
}
|
}
|
||||||
else {
|
else if (correspondingElement instanceof JetNamedDeclaration) {
|
||||||
JetNamedDeclaration namedDeclaration = (JetNamedDeclaration) correspondingElement;
|
JetNamedDeclaration namedDeclaration = (JetNamedDeclaration) correspondingElement;
|
||||||
label = namedDeclaration.getName();
|
label = namedDeclaration.getName();
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
label = "this";
|
||||||
|
}
|
||||||
|
|
||||||
instructionDump.append("== ").append(label).append(" ==\n");
|
instructionDump.append("== ").append(label).append(" ==\n");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user