diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/orderUtil.kt b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/orderUtil.kt index 9d1a3c0dff31..0ea2dced77ac 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/orderUtil.kt +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/controlFlow/orderUtil.kt @@ -1,37 +1,29 @@ -/* - * Copyright 2000-2017 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. - */ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. @file:JvmName("OrderUtil") package org.jetbrains.plugins.groovy.lang.psi.controlFlow +import com.intellij.util.ArrayUtil.EMPTY_INT_ARRAY import org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl.InstructionImpl import java.util.* private val fakeRoot = InstructionImpl(null) -fun reversedPostOrder(flow: Array): IntArray = postOrder(flow).reversedArray() +@JvmOverloads +fun reversedPostOrder(flow: Array, reachable: Boolean = false): IntArray = postOrder(flow, reachable).reversedArray() -fun postOrder(flow: Array): IntArray { - val N = flow.size - val result = IntArray(N) +fun postOrder(flow: Array, reachable: Boolean): IntArray { + val n = flow.size + if (n == 0) return EMPTY_INT_ARRAY + + val result = IntArray(n) { -1 } var resultIndex = 0 - val visited = BooleanArray(N) + val visited = BooleanArray(n) val stack: Deque>> = LinkedList() - stack.push(fakeRoot to flow.iterator()) + + val rootIterator = if (reachable) listOf(flow[0]).iterator() else flow.iterator() + stack.push(fakeRoot to rootIterator) while (!stack.isEmpty()) { val (instruction, iterator) = stack.peek() @@ -51,8 +43,13 @@ fun postOrder(flow: Array): IntArray { } } - assert(resultIndex == N) - return result + if (reachable) { + assert(resultIndex <= n) + } + else { + assert(resultIndex == n) + } + return if (resultIndex == n) result else result.take(resultIndex).toIntArray() } private inline fun Iterator.firstOrNull(predicate: (T) -> Boolean): T? { diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/DFAEngine.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/DFAEngine.java index 9d248e9bf8a3..45f0b73913ca 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/DFAEngine.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/DFAEngine.java @@ -1,18 +1,4 @@ -/* - * Copyright 2000-2017 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. - */ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package org.jetbrains.plugins.groovy.lang.psi.dataFlow; import com.intellij.openapi.progress.ProgressManager; @@ -84,7 +70,7 @@ public class DFAEngine { final List info = new ArrayList<>(Collections.nCopies(n, myDfa.initial())); final CallEnvironment env = new MyCallEnvironment(n); - final WorkList workList = new WorkList(getFlowOrder()); + final WorkList workList = new WorkList(n, getFlowOrder()); while (!workList.isEmpty()) { ProgressManager.checkCanceled(); @@ -108,10 +94,10 @@ public class DFAEngine { @NotNull private int[] getFlowOrder() { if (myDfa.isForward()) { - return reversedPostOrder(myFlow); + return reversedPostOrder(myFlow, myDfa.isReachable()); } else { - return postOrder(myFlow); + return postOrder(myFlow, myDfa.isReachable()); } } diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/DfaInstance.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/DfaInstance.java index 057439e3bc70..f79357571960 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/DfaInstance.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/DfaInstance.java @@ -1,18 +1,4 @@ -/* - * Copyright 2000-2017 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. - */ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package org.jetbrains.plugins.groovy.lang.psi.dataFlow; import org.jetbrains.annotations.NotNull; @@ -31,4 +17,11 @@ public interface DfaInstance { default boolean isForward() { return true; } + + /** + * @return {@code true} if this instance expects only instructions reachable from root + */ + default boolean isReachable() { + return false; + } } diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/WorkList.kt b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/WorkList.kt index 4a15aafd0662..68878878871d 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/WorkList.kt +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/WorkList.kt @@ -1,23 +1,9 @@ -/* - * Copyright 2000-2017 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. - */ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package org.jetbrains.plugins.groovy.lang.psi.dataFlow import java.util.* -internal class WorkList(order: IntArray) { +internal class WorkList(flowSize: Int, order: IntArray) { private val mySize: Int = order.size /** @@ -27,7 +13,7 @@ internal class WorkList(order: IntArray) { /** * Mapping: instruction number -> index in [myOrder] array */ - private val myInstructionToOrder: IntArray = IntArray(mySize) + private val myInstructionToOrder: IntArray = IntArray(flowSize) /** * Mapping: index -> whether instruction number needs to be processed * diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/readWrite/ReadBeforeWriteInstance.kt b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/readWrite/ReadBeforeWriteInstance.kt index 58613c4946b1..d4a594d20857 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/readWrite/ReadBeforeWriteInstance.kt +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/readWrite/ReadBeforeWriteInstance.kt @@ -1,18 +1,4 @@ -/* - * Copyright 2000-2017 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. - */ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package org.jetbrains.plugins.groovy.lang.psi.dataFlow.readWrite import gnu.trove.TObjectIntHashMap @@ -41,4 +27,6 @@ class ReadBeforeWriteInstance(val nameIndex: TObjectIntHashMap, val only } override fun initial(): ReadBeforeWriteState = ReadBeforeWriteState.bottom + + override fun isReachable(): Boolean = true } \ No newline at end of file