From 7d7d33b2ee434a719c31b82235523e7a65b08b1b Mon Sep 17 00:00:00 2001 From: svtk Date: Mon, 7 Nov 2011 19:49:32 +0400 Subject: [PATCH] KT-443 Write allowed to super.val --- .../jet/lang/cfg/JetControlFlowProcessor.java | 45 +++++++++--- .../lang/cfg/JetFlowInformationProvider.java | 4 +- .../LocalDeclarationInstruction.java | 17 +---- .../cfg/AnonymousInitializers.instructions | 41 ++++++++--- compiler/testData/cfg/Basic.instructions | 6 +- compiler/testData/cfg/Finally.instructions | 12 ++-- .../cfg/LocalDeclarations.instructions | 72 +++++++++---------- .../quick/regressions/kt439.jet | 2 +- .../quick/regressions/kt443.jet | 14 ++++ .../jetbrains/jet/cfg/JetControlFlowTest.java | 8 ++- 10 files changed, 136 insertions(+), 85 deletions(-) create mode 100644 compiler/testData/checkerWithErrorTypes/quick/regressions/kt443.jet diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java index 0a32419c9a2..b65c0db05c5 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java @@ -45,6 +45,18 @@ public class JetControlFlowProcessor { } builder.exitSubroutine(subroutineElement); } + + private void processLocalDeclaration(@NotNull JetDeclaration subroutineElement, @NotNull JetExpression body) { + processLocalDeclaration(subroutineElement, Collections.singletonList(body)); + } + + private void processLocalDeclaration(@NotNull JetDeclaration subroutineElement, @NotNull List body) { + Label afterDeclaration = builder.createUnboundLabel(); + builder.nondeterministicJump(afterDeclaration); + generateSubroutineControlFlow(subroutineElement, body); + builder.bindLabel(afterDeclaration); + } + private class CFPVisitor extends JetVisitorVoid { private final boolean inCondition; @@ -548,10 +560,7 @@ public class JetControlFlowProcessor { public void visitNamedFunction(JetNamedFunction function) { JetExpression bodyExpression = function.getBodyExpression(); if (bodyExpression != null) { - Label afterFunctionLabel = builder.createUnboundLabel(); - builder.nondeterministicJump(afterFunctionLabel); - generate(function, bodyExpression); - builder.bindLabel(afterFunctionLabel); + processLocalDeclaration(function, bodyExpression); } } @@ -561,10 +570,7 @@ public class JetControlFlowProcessor { JetBlockExpression bodyExpression = functionLiteral.getBodyExpression(); if (bodyExpression != null) { List statements = bodyExpression.getStatements(); - Label afterFunctionLiteralLabel = builder.createUnboundLabel(); - builder.nondeterministicJump(afterFunctionLiteralLabel); - generateSubroutineControlFlow(functionLiteral, statements); - builder.bindLabel(afterFunctionLiteralLabel); + processLocalDeclaration(functionLiteral, statements); } builder.read(expression); } @@ -644,6 +650,14 @@ public class JetControlFlowProcessor { } } + @Override + public void visitPropertyAccessor(JetPropertyAccessor accessor) { + JetExpression bodyExpression = accessor.getBodyExpression(); + if (bodyExpression != null) { + processLocalDeclaration(accessor, bodyExpression); + } + } + @Override public void visitTupleExpression(JetTupleExpression expression) { for (JetExpression entry : expression.getEntries()) { @@ -788,12 +802,21 @@ public class JetControlFlowProcessor { private void visitClassOrObject(JetClassOrObject classOrObject) { List declarations = classOrObject.getDeclarations(); + List properties = Lists.newArrayList(); for (JetDeclaration declaration : declarations) { - if (declaration instanceof JetProperty || declaration instanceof JetClassInitializer) { - //declaration.accept(this); + if (declaration instanceof JetProperty) { + value(declaration, inCondition); + properties.add((JetProperty) declaration); + } + else if (declaration instanceof JetClassInitializer) { value(declaration, inCondition); } - } + } + for (JetProperty property : properties) { + for (JetPropertyAccessor accessor : property.getAccessors()) { + value(accessor, inCondition); + } + } } @Override diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java index 342d6f9d631..cef9bbdfda4 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java @@ -250,9 +250,7 @@ public class JetFlowInformationProvider { for (Instruction instruction : pseudocode.getInstructions()) { if (instruction instanceof LocalDeclarationInstruction) { JetElement element = ((LocalDeclarationInstruction) instruction).getElement(); - if (element instanceof JetNamedFunction) { - markUninitializedVariables(element, false, analyzeLocalDeclaration); - } + markUninitializedVariables(element, false, analyzeLocalDeclaration); } } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/LocalDeclarationInstruction.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/LocalDeclarationInstruction.java index 587a7ee76f4..67a4e220fcd 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/LocalDeclarationInstruction.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/LocalDeclarationInstruction.java @@ -2,10 +2,7 @@ package org.jetbrains.jet.lang.cfg.pseudocode; import com.google.common.collect.Lists; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.psi.JetClass; -import org.jetbrains.jet.lang.psi.JetDeclaration; -import org.jetbrains.jet.lang.psi.JetFunction; -import org.jetbrains.jet.lang.psi.JetObjectDeclaration; +import org.jetbrains.jet.lang.psi.*; import java.util.ArrayList; import java.util.Collection; @@ -49,16 +46,6 @@ public class LocalDeclarationInstruction extends InstructionWithNext { @Override public String toString() { - String kind = "!"; - if (element instanceof JetFunction) { - kind = "f"; - } - else if (element instanceof JetClass) { - kind = "c"; - } - else if (element instanceof JetObjectDeclaration) { - kind = "o"; - } - return "d" + kind + "(" + element.getText() + ")"; + return "d" + "(" + element.getText() + ")"; } } diff --git a/compiler/testData/cfg/AnonymousInitializers.instructions b/compiler/testData/cfg/AnonymousInitializers.instructions index 9b932ef3926..3f5a19173d7 100644 --- a/compiler/testData/cfg/AnonymousInitializers.instructions +++ b/compiler/testData/cfg/AnonymousInitializers.instructions @@ -1,3 +1,16 @@ +== get_j == +get() = 20 +--------------------- +l3: + NEXT:[r(20)] PREV:[] + r(20) NEXT:[] PREV:[] +l4: + NEXT:[] PREV:[r(20)] +error: + NEXT:[] PREV:[] +sink: + NEXT:[] PREV:[] +===================== == AnonymousInitializers == class AnonymousInitializers() { val k = 34 @@ -16,15 +29,27 @@ class AnonymousInitializers() { } --------------------- l0: - NEXT:[r(34)] PREV:[] - r(34) NEXT:[w(k)] PREV:[] - 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:[] PREV:[r(13)] + NEXT:[r(34)] PREV:[] + r(34) NEXT:[w(k)] PREV:[] + 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:[jmp?(l2)] PREV:[r(13)] + jmp?(l2) NEXT:[, d(get() = 20)] PREV:[w($i)] + d(get() = 20) NEXT:[] PREV:[jmp?(l2)] l1: - NEXT:[] PREV:[w($i)] +l2: + NEXT:[] PREV:[jmp?(l2)] +error: + NEXT:[] PREV:[] +sink: + NEXT:[] PREV:[d(get() = 20), ] +l3: + NEXT:[r(20)] PREV:[] + r(20) NEXT:[] PREV:[] +l4: + NEXT:[] PREV:[r(20)] error: NEXT:[] PREV:[] sink: diff --git a/compiler/testData/cfg/Basic.instructions b/compiler/testData/cfg/Basic.instructions index 338eae2cd99..e199fb184fe 100644 --- a/compiler/testData/cfg/Basic.instructions +++ b/compiler/testData/cfg/Basic.instructions @@ -43,8 +43,8 @@ l0: r(foo(a, 3)) NEXT:[r(genfun)] PREV:[r(foo)] r(genfun) NEXT:[r(genfun())] PREV:[r(foo(a, 3))] r(genfun()) NEXT:[jmp?(l2)] PREV:[r(genfun)] - jmp?(l2) NEXT:[r({1}), df({1})] PREV:[r(genfun())] - df({1}) NEXT:[] PREV:[jmp?(l2)] + jmp?(l2) NEXT:[r({1}), d({1})] PREV:[r(genfun())] + d({1}) NEXT:[] PREV:[jmp?(l2)] l2: r({1}) NEXT:[r(flfun)] PREV:[jmp?(l2)] r(flfun) NEXT:[r(flfun {1})] PREV:[r({1})] @@ -77,7 +77,7 @@ l1: error: NEXT:[] PREV:[] sink: - NEXT:[] PREV:[df({1}), ] + NEXT:[] PREV:[d({1}), ] l3: NEXT:[r(1)] PREV:[] r(1) NEXT:[] PREV:[] diff --git a/compiler/testData/cfg/Finally.instructions b/compiler/testData/cfg/Finally.instructions index f79f89e16cd..8802a5daeaa 100644 --- a/compiler/testData/cfg/Finally.instructions +++ b/compiler/testData/cfg/Finally.instructions @@ -100,8 +100,8 @@ l0: NEXT:[jmp?(l2)] PREV:[] jmp?(l2) NEXT:[r(2), r(1)] PREV:[] r(1) NEXT:[jmp?(l3)] PREV:[jmp?(l2)] - jmp?(l3) NEXT:[r({ () => if (2 > 3) { retur..), df({ () => if (2 > 3) { retu..)] PREV:[r(1)] - df({ () => + jmp?(l3) NEXT:[r({ () => if (2 > 3) { retur..), d({ () => if (2 > 3) { retur..)] PREV:[r(1)] + d({ () => if (2 > 3) { return@ } @@ -119,7 +119,7 @@ l1: error: NEXT:[] PREV:[] sink: - NEXT:[] PREV:[df({ () => if (2 > 3) { retu..), ] + NEXT:[] PREV:[d({ () => if (2 > 3) { retur..), ] l4: NEXT:[r(2)] PREV:[] r(2) NEXT:[r(3)] PREV:[] @@ -191,8 +191,8 @@ fun t4() { --------------------- l0: NEXT:[jmp?(l2)] PREV:[] - jmp?(l2) NEXT:[r({ () => try { 1 if (2 > 3)..), df({ () => try { 1 if (2 > 3..)] PREV:[] - df({ () => + jmp?(l2) NEXT:[r({ () => try { 1 if (2 > 3)..), d({ () => try { 1 if (2 > 3)..)] PREV:[] + d({ () => try { 1 if (2 > 3) { @@ -218,7 +218,7 @@ l1: error: NEXT:[] PREV:[] sink: - NEXT:[] PREV:[df({ () => try { 1 if (2 > 3..), ] + NEXT:[] PREV:[d({ () => try { 1 if (2 > 3)..), ] l3: NEXT:[jmp?(l5)] PREV:[] jmp?(l5) NEXT:[r(2), r(1)] PREV:[] diff --git a/compiler/testData/cfg/LocalDeclarations.instructions b/compiler/testData/cfg/LocalDeclarations.instructions index 45554a4d8b1..5c28d11a9fc 100644 --- a/compiler/testData/cfg/LocalDeclarations.instructions +++ b/compiler/testData/cfg/LocalDeclarations.instructions @@ -166,25 +166,25 @@ fun test3() { } --------------------- l0: - NEXT:[jmp?(l2)] PREV:[] - jmp?(l2) NEXT:[r(object { val y : Int fun i..), df(fun inner_bar() { y = 10 ..)] PREV:[] - df(fun inner_bar() { + NEXT:[jmp?(l2)] PREV:[] + jmp?(l2) NEXT:[r(object { val y : Int fun i..), d(fun inner_bar() { y = 10 }) ] PREV:[] + d(fun inner_bar() { y = 10 - }) NEXT:[] PREV:[jmp?(l2)] + }) NEXT:[] PREV:[jmp?(l2)] l2: r(object { val y : Int fun inner_bar() { y = 10 } - }) NEXT:[w(a)] PREV:[jmp?(l2)] - w(a) NEXT:[] PREV:[r(object { val y : Int fun i..)] + }) NEXT:[w(a)] PREV:[jmp?(l2)] + w(a) NEXT:[] PREV:[r(object { val y : Int fun i..)] l1: - NEXT:[] PREV:[w(a)] + NEXT:[] PREV:[w(a)] error: - NEXT:[] PREV:[] + NEXT:[] PREV:[] sink: - NEXT:[] PREV:[df(fun inner_bar() { y = 10 ..), ] + NEXT:[] PREV:[d(fun inner_bar() { y = 10 }) , ] l3: NEXT:[r(10)] PREV:[] r(10) NEXT:[w(y)] PREV:[] @@ -227,13 +227,13 @@ fun test4() { } --------------------- l0: - NEXT:[r(1)] PREV:[] - r(1) NEXT:[w($x)] PREV:[] - w($x) NEXT:[jmp?(l2)] PREV:[r(1)] - jmp?(l2) NEXT:[r(object { val x : Int val y..), df(fun ggg() { y = 10 }) ] PREV:[w($x)] - df(fun ggg() { + NEXT:[r(1)] PREV:[] + r(1) NEXT:[w($x)] PREV:[] + w($x) NEXT:[jmp?(l2)] PREV:[r(1)] + jmp?(l2) NEXT:[r(object { val x : Int val y..), d(fun ggg() { y = 10 }) ] PREV:[w($x)] + d(fun ggg() { y = 10 - }) NEXT:[] PREV:[jmp?(l2)] + }) NEXT:[] PREV:[jmp?(l2)] l2: r(object { val x : Int @@ -244,14 +244,14 @@ l2: fun ggg() { y = 10 } - }) NEXT:[w(a)] PREV:[jmp?(l2)] - w(a) NEXT:[] PREV:[r(object { val x : Int val y..)] + }) NEXT:[w(a)] PREV:[jmp?(l2)] + w(a) NEXT:[] PREV:[r(object { val x : Int val y..)] l1: - NEXT:[] PREV:[w(a)] + NEXT:[] PREV:[w(a)] error: - NEXT:[] PREV:[] + NEXT:[] PREV:[] sink: - NEXT:[] PREV:[df(fun ggg() { y = 10 }) , ] + NEXT:[] PREV:[d(fun ggg() { y = 10 }) , ] l3: NEXT:[r(10)] PREV:[] r(10) NEXT:[w(y)] PREV:[] @@ -312,20 +312,20 @@ fun test5() { } --------------------- l0: - NEXT:[r(1)] PREV:[] - r(1) NEXT:[w(x)] PREV:[] - w(x) NEXT:[r(2)] PREV:[r(1)] - r(2) NEXT:[w($x)] PREV:[w(x)] - w($x) NEXT:[jmp?(l2)] PREV:[r(2)] - jmp?(l2) NEXT:[jmp?(l5), df(fun foo() { x = 3 }) ] PREV:[w($x)] - df(fun foo() { + NEXT:[r(1)] PREV:[] + r(1) NEXT:[w(x)] PREV:[] + w(x) NEXT:[r(2)] PREV:[r(1)] + r(2) NEXT:[w($x)] PREV:[w(x)] + w($x) NEXT:[jmp?(l2)] PREV:[r(2)] + jmp?(l2) NEXT:[jmp?(l5), d(fun foo() { x = 3 }) ] PREV:[w($x)] + d(fun foo() { x = 3 - }) NEXT:[] PREV:[jmp?(l2)] + }) NEXT:[] PREV:[jmp?(l2)] l2: - jmp?(l5) NEXT:[r(object { var x = 1 { $x = ..), df(fun bar() { x = 4 }) ] PREV:[jmp?(l2)] - df(fun bar() { + jmp?(l5) NEXT:[r(object { var x = 1 { $x = ..), d(fun bar() { x = 4 }) ] PREV:[jmp?(l2)] + d(fun bar() { x = 4 - }) NEXT:[] PREV:[jmp?(l5)] + }) NEXT:[] PREV:[jmp?(l5)] l5: r(object { var x = 1 @@ -338,14 +338,14 @@ l5: fun bar() { x = 4 } - }) NEXT:[w(a)] PREV:[jmp?(l5)] - w(a) NEXT:[] PREV:[r(object { var x = 1 { $x = ..)] + }) NEXT:[w(a)] PREV:[jmp?(l5)] + w(a) NEXT:[] PREV:[r(object { var x = 1 { $x = ..)] l1: - NEXT:[] PREV:[w(a)] + NEXT:[] PREV:[w(a)] error: - NEXT:[] PREV:[] + NEXT:[] PREV:[] sink: - NEXT:[] PREV:[df(fun foo() { x = 3 }) , df(fun bar() { x = 4 }) , ] + NEXT:[] PREV:[d(fun foo() { x = 3 }) , d(fun bar() { x = 4 }) , ] l3: NEXT:[r(3)] PREV:[] r(3) NEXT:[w(x)] PREV:[] diff --git a/compiler/testData/checkerWithErrorTypes/quick/regressions/kt439.jet b/compiler/testData/checkerWithErrorTypes/quick/regressions/kt439.jet index 49bd3b8b550..a914cc023c5 100644 --- a/compiler/testData/checkerWithErrorTypes/quick/regressions/kt439.jet +++ b/compiler/testData/checkerWithErrorTypes/quick/regressions/kt439.jet @@ -1,4 +1,4 @@ -// KT-439 Support labeled function lliterals in call arguments +// KT-439 Support labeled function literals in call arguments inline fun run1(body : fun() : T) : T = body() diff --git a/compiler/testData/checkerWithErrorTypes/quick/regressions/kt443.jet b/compiler/testData/checkerWithErrorTypes/quick/regressions/kt443.jet new file mode 100644 index 00000000000..54831513552 --- /dev/null +++ b/compiler/testData/checkerWithErrorTypes/quick/regressions/kt443.jet @@ -0,0 +1,14 @@ +// KT-443 Write allowed to super.val + +open class M() { + open val b: Int = 5 +} + +class N() : M() { + val a : Int + get() { + super.b = super.b + 1 + return super.b + 1 + } + override val b: Int = a + 1 +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/cfg/JetControlFlowTest.java b/compiler/tests/org/jetbrains/jet/cfg/JetControlFlowTest.java index bfee30ffcba..2a3e2780fc3 100644 --- a/compiler/tests/org/jetbrains/jet/cfg/JetControlFlowTest.java +++ b/compiler/tests/org/jetbrains/jet/cfg/JetControlFlowTest.java @@ -100,7 +100,7 @@ public class JetControlFlowTest extends JetLiteFixture { for (Pseudocode pseudocode : pseudocodes) { JetElement correspondingElement = pseudocode.getCorrespondingElement(); String label = ""; - assert (correspondingElement instanceof JetNamedDeclaration || correspondingElement instanceof JetConstructor) : + assert (correspondingElement instanceof JetNamedDeclaration || correspondingElement instanceof JetConstructor || correspondingElement instanceof JetPropertyAccessor) : "Unexpected element class is pseudocode: " + correspondingElement.getClass(); if (correspondingElement instanceof JetFunctionLiteral) { label = "anonymous_" + i++; @@ -109,7 +109,11 @@ public class JetControlFlowTest extends JetLiteFixture { JetNamedDeclaration namedDeclaration = (JetNamedDeclaration) correspondingElement; label = namedDeclaration.getName(); } - else { + else if (correspondingElement instanceof JetPropertyAccessor) { + String propertyName = ((JetProperty) correspondingElement.getParent()).getName(); + label = (((JetPropertyAccessor) correspondingElement).isGetter() ? "get" : "set") + "_" + propertyName; + } + else if (correspondingElement instanceof JetConstructor) { label = "this"; }