From 3ef1c53a850f6bdb31bb1bf01c2c561f125286a0 Mon Sep 17 00:00:00 2001 From: Grigorii Kirgizov Date: Mon, 27 Jul 2020 11:09:18 +0300 Subject: [PATCH] Move TermWalker from tests package to core.internal to reuse for MPSCR-66 Also convert it to Kotlin --- .../logic/reactor/core/internal/TermWalker.kt | 77 +++++++++++++++++ .../test/AssertStructurallyEquivalent.java | 86 +++---------------- 2 files changed, 91 insertions(+), 72 deletions(-) create mode 100644 reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/TermWalker.kt diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/TermWalker.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/TermWalker.kt new file mode 100644 index 00000000..ba704637 --- /dev/null +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/TermWalker.kt @@ -0,0 +1,77 @@ +/* + * Copyright 2014-2020 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 jetbrains.mps.logic.reactor.core.internal + +import jetbrains.mps.logic.reactor.logical.Logical +import jetbrains.mps.logic.reactor.logical.LogicalOwner +import jetbrains.mps.unification.Term +import java.util.* + +/** + * @author Fedor Isakov + */ +class TermWalker(vararg visitors: TermVisitor) { + + abstract class TermVisitor(private val kind: Term.Kind) { + fun applicableTo(): Term.Kind = kind + + @Throws(Exception::class) + abstract fun visit(t: T): MutableCollection + + } + + private val visitorMap: MutableMap> = EnumMap(Term.Kind::class.java) + + init { + for (visitor in visitors) { + visitorMap[visitor.applicableTo()] = visitor + } + } + + @Throws(Exception::class) + fun walk(term: Term) { + walk(term, IdentityHashMap()) + } + + @Throws(Exception::class) + private fun walk(term: Term, visited: MutableMap) { + if (term.`is`(Term.Kind.FUN)) { + visited[term] = SINGLETON + } + val arguments = switchClass(term) + for (arg in arguments) { + if (visited.containsKey(arg)) { + continue + } + walk(arg, visited) + } + } + + @Throws(Exception::class) + private fun switchClass(term: Term): Collection { + for ((key, value1) in visitorMap) { + if (term.`is`(key)) { + val value = value1 as TermVisitor + return value.visit(term) + } + } + return emptyList() + } + + companion object { + private val SINGLETON = Any() + } +} \ No newline at end of file diff --git a/reactor/Test/test/jetbrains/mps/unification/test/AssertStructurallyEquivalent.java b/reactor/Test/test/jetbrains/mps/unification/test/AssertStructurallyEquivalent.java index 06887b18..6ea33132 100644 --- a/reactor/Test/test/jetbrains/mps/unification/test/AssertStructurallyEquivalent.java +++ b/reactor/Test/test/jetbrains/mps/unification/test/AssertStructurallyEquivalent.java @@ -16,6 +16,7 @@ package jetbrains.mps.unification.test; +import jetbrains.mps.logic.reactor.core.internal.TermWalker; import jetbrains.mps.unification.Term; import static org.junit.Assert.*; @@ -32,40 +33,40 @@ public class AssertStructurallyEquivalent { signature.setWalkers( // first pass new TermWalker( - new TermVisitor(Term.Kind.FUN) { + new TermWalker.TermVisitor(Term.Kind.FUN) { @Override public Collection visit(Term term) throws Exception { signature.label(term); return term.arguments(); } - } - , - new TermVisitor(Term.Kind.REF) { - @Override - public Collection visit(Term ref) throws Exception { - if (ref.get().is(Term.Kind.FUN)) { - return Collections.singletonList(ref.get()); + }, + new TermWalker.TermVisitor(Term.Kind.REF) { + @Override + public Collection visit(Term ref) throws Exception { + if (ref.get().is(Term.Kind.FUN)) { + return Collections.singletonList(ref.get()); + } + return Collections.emptyList(); } - return Collections.emptyList(); } - } ), // second pass new TermWalker( - new TermVisitor(Term.Kind.FUN) { + new TermWalker.TermVisitor(Term.Kind.FUN) { @Override public Collection visit(Term term) throws Exception { signature.appendSignature("@").append(signature.getLabel(term)).append(term.symbol()); return term.arguments(); } }, - new TermVisitor(Term.Kind.VAR) { + new TermWalker.TermVisitor(Term.Kind.VAR) { @Override public Collection visit(Term var) throws Exception { signature.appendSignature("$").append(var.symbol()); return Collections.emptyList(); } - }, new TermVisitor(Term.Kind.REF) { + }, + new TermWalker.TermVisitor(Term.Kind.REF) { @Override public Collection visit(Term ref) throws Exception { if (ref.get().is(Term.Kind.FUN)) { @@ -139,63 +140,4 @@ public class AssertStructurallyEquivalent { } } - private static abstract class TermVisitor { - - private Term.Kind kind; - - public TermVisitor(Term.Kind kind) { - this.kind = kind; - } - - public Term.Kind applicableTo() { - return kind; - } - - - - public abstract Collection visit(T t) throws Exception ; - - } - - private static class TermWalker { - - private static Object SINGLETON = new Object(); - - private Map> visitorMap = new HashMap>(); - - public TermWalker(TermVisitor... visitors) { - for (TermVisitor visitor : visitors) { - visitorMap.put(visitor.applicableTo(), visitor); - } - } - - public void walk(Term term) throws Exception { - walk(term, new IdentityHashMap()); - } - - private void walk(Term term, Map visited) throws Exception { - if (term.is(Term.Kind.FUN)) { - visited.put(term, SINGLETON); - } - Collection arguments = switchClass(term); - for (Term arg : arguments) { - if (visited.containsKey(arg)) { - continue; - } - walk(arg, visited); - } - } - - private Collection switchClass(Term term) throws Exception { - for (Map.Entry> e : visitorMap.entrySet()) { - if (term.is(e.getKey())) { - TermVisitor value = (TermVisitor) e.getValue(); - return value.visit(term); - } - } - return Collections.emptyList(); - } - - } - }