Browse Source

added modified reflection extension

Simon Van Mierlo 7 years ago
parent
commit
de372972dd

+ 1 - 0
debugging_environment/NetLogo/Reflection-Extension/.bundledFiles

@@ -0,0 +1 @@
+C:\Users\Simon\Documents\Unief\14-17.PhD\16.01.InternshipAutodesk\Projects\ds_debugger\debugging_environment\NetLogo\Reflection-Extension\target\scala-2.12\reflection.jar->reflection.jar

+ 9 - 0
debugging_environment/NetLogo/Reflection-Extension/.gitignore

@@ -0,0 +1,9 @@
+/bin/*
+*.class
+target
+target/*
+*.cache
+*.jar
+*.jar.*
+*.xml
+*.zip

+ 18 - 0
debugging_environment/NetLogo/Reflection-Extension/README.md

@@ -0,0 +1,18 @@
+# Reflection-Extension
+This extension allows you to extract names of breeds, procedures, and variables (global and breed-specific ones).
+It has a few simple reporters:
+
+## `globals`
+`reflection:globals` reports a list with the names of all global variables
+
+## `breeds`
+`reflection:breeds` reports a list of all breed names, and all their variables, default variables included.
+
+## `procedures`
+`reflection:procedures` reports a list of all procedures and their arguments. It also tells you whether they are reporters or commands.
+
+## `current-procedure`
+`reflection:current-procedure` reports the name of the current procedure.
+
+## `callers`
+`reflection:callers` reports the name of the callers to the current procedure as a list. If this is inside a procedure `foo`, which is called by `bar` this will report `["FOO" "BAR"]`.

+ 47 - 0
debugging_environment/NetLogo/Reflection-Extension/build.sbt

@@ -0,0 +1,47 @@
+enablePlugins(org.nlogo.build.NetLogoExtension)
+
+scalaSource in Compile := baseDirectory.value / "src" / "main"
+
+scalaSource in Test := baseDirectory.value / "src" / "test"
+
+netLogoClassManager := "org.nlogo.extensions.reflection.NetLogoReflectionScala"
+
+netLogoVersion := "6.0.3"
+
+netLogoTarget := NetLogoExtension.directoryTarget(baseDirectory.value)
+
+lazy val root = (project in file(".")).
+  settings(
+    inThisBuild(List(
+      scalaVersion := "2.12.1"
+      ,version      := "0.1.0-SNAPSHOT"
+    ))
+    ,name :=  "reflection"
+    ,libraryDependencies ++= Seq(
+      "org.picocontainer"  % "picocontainer" % "2.13.6" % "test",
+      "org.scalatest" %% "scalatest" % "3.0.0" % "test",
+      "org.ow2.asm" % "asm-all" % "5.0.3"  % "test"
+    )
+  )
+
+val moveToRefDir = taskKey[Unit]("add all resources to Reflection directory")
+
+val refDirectory = settingKey[File]("directory that extension is moved to for testing")
+
+refDirectory := baseDirectory.value / "extensions" / "reflection"
+
+moveToRefDir := {
+  (packageBin in Compile).value
+  val testTarget = NetLogoExtension.directoryTarget(refDirectory.value)
+  testTarget.create(NetLogoExtension.netLogoPackagedFiles.value)
+  val testResources = (baseDirectory.value / "test").filter(_.isFile)
+  for (file <- testResources.get)
+    IO.copyFile(file, refDirectory.value / "test" / IO.relativize(baseDirectory.value / "test", file).get)
+}
+
+test in Test := {
+  IO.createDirectory(refDirectory.value)
+  moveToRefDir.value
+  (test in Test).value
+  IO.delete(refDirectory.value)
+}

+ 1 - 0
debugging_environment/NetLogo/Reflection-Extension/project/build.properties

@@ -0,0 +1 @@
+sbt.version=1.1.6

+ 6 - 0
debugging_environment/NetLogo/Reflection-Extension/project/plugins.sbt

@@ -0,0 +1,6 @@
+resolvers += Resolver.url(
+  "NetLogo-JVM",
+  url("http://dl.bintray.com/content/netlogo/NetLogo-JVM"))(
+    Resolver.ivyStylePatterns)
+
+addSbtPlugin("org.nlogo" % "netlogo-extension-plugin" % "3.2")

+ 155 - 0
debugging_environment/NetLogo/Reflection-Extension/src/main/NetLogoReflectionScala.scala

@@ -0,0 +1,155 @@
+package org.nlogo.extensions.reflection
+
+import org.nlogo.core.{ Program, Syntax }
+import org.nlogo.core.Syntax.{ NumberType, ListType }
+import org.nlogo.app.App
+import org.nlogo.nvm.ExtensionContext
+import org.nlogo.api.{ LogoListBuilder, Reporter, Command, Context, Argument, PrimitiveManager, DefaultClassManager, ExtensionException }
+import org.nlogo.api.ScalaConversions._
+import org.nlogo.headless.HeadlessWorkspace
+import org.nlogo.lite.LiteWorkspace
+
+class NetLogoReflectionScala extends DefaultClassManager {
+  override def load(manager: PrimitiveManager) {
+    manager.addPrimitive("globals", new Globals)
+    manager.addPrimitive("breeds", new Breeds)
+    manager.addPrimitive("procedures", new Procedures);
+    manager.addPrimitive("current-procedure", new CurrentProcedure);
+    manager.addPrimitive("callers", new Callers);
+    manager.addPrimitive("turtles", new Turtles);
+    //manager.addPrimitive("set-framerate", new SetFramerate);
+  }
+}
+
+class Globals extends Reporter {
+  override def getSyntax = Syntax.reporterSyntax(ret = ListType)
+  override def report(args: Array[Argument], context: Context): AnyRef = {
+    context match {
+      case extContext: ExtensionContext => {
+        if (extContext.workspace == null) {
+          throw new ExtensionException(s"We need a workspace : $extContext");
+        }
+        val observer = extContext.workspace.world.observer
+        (0 until observer.variables.length).map(observer.variableName(_)).toLogoList
+      }
+      case _ => throw new ExtensionException(s"Unknown context given : $context")
+    }
+  }
+}
+
+class Breeds extends Reporter {
+  override def getSyntax = Syntax.reporterSyntax(ret = ListType)
+  override def report(args: Array[Argument], context: Context): AnyRef = {
+    context match {
+      case extContext: ExtensionContext => {
+        val breeds = new LogoListBuilder
+        // add turtle vars as a separate tuple
+        val turtleInfo = new LogoListBuilder
+        turtleInfo.add("TURTLES")
+        val workspace = extContext.workspace;
+        val turtleVars = workspace.world.program.turtleVars.keys.toVector.toLogoList
+        turtleInfo.add(turtleVars)
+        breeds.add(turtleInfo.toLogoList)
+        // now the rest of the breeds
+        val otherBreeds = workspace.world.program.breeds.map {
+          case (name, vars) =>
+            val breedInfo = new LogoListBuilder
+            breedInfo.add(name)
+            breedInfo.add(vars.owns.toLogoList)
+            breedInfo.toLogoList
+        }
+        otherBreeds.foreach(breeds.add)
+        breeds.toLogoList
+      }
+      case _ => throw new ExtensionException(s"Unknown context given : $context")
+    }
+  }
+}
+
+class Turtles extends Reporter {
+  override def getSyntax = Syntax.reporterSyntax(ret = ListType)
+  override def report(args: Array[Argument], context: Context): AnyRef = {
+    context match {
+      case extContext: ExtensionContext => {
+        val turtles = extContext.workspace.world.turtles.agents
+        val allvariables = new LogoListBuilder
+        turtles.forEach(turtle => {
+          allvariables.add((0 until turtle.variables.length).map(turtle.getVariable(_).toString).toLogoList)          
+        })
+        allvariables.toLogoList
+      }
+      case _ => throw new ExtensionException(s"Unknown context given : $context")
+    }
+  }
+}
+
+/*
+class SetFramerate extends Command {
+  override def getSyntax = Syntax.reporterSyntax(ret = ListType)
+  override def perform(args: Array[Argument], context: Context): AnyRef = {
+    context match {
+      case extContext: ExtensionContext => {
+        if (extContext.workspace.isInstanceOf[HeadlessWorkspace]) {
+          extContext.workspace.asInstanceOf[HeadlessWorkspace].frameRate(5.0)
+        } else if (extContext.workspace.isInstanceOf[LiteWorkspace]) {
+          extContext.workspace.asInstanceOf[LiteWorkspace].frameRate(5.0)
+        }
+      }
+      case _ => throw new ExtensionException(s"Unknown context given : $context")
+    }
+  }
+} 
+*/
+
+class Procedures extends Reporter {
+  override def getSyntax = Syntax.reporterSyntax(ret = ListType)
+  override def report(args: Array[Argument], context: Context): AnyRef = {
+    context match {
+      case extContext: ExtensionContext => {
+        var workspace = extContext.workspace
+        workspace.procedures.map {
+          case (name, procedure) =>
+            val procedureInfo = new LogoListBuilder
+            procedureInfo.add(name)
+            procedureInfo.add(if (procedure.isReporter) "REPORTER" else "COMMAND")
+            procedureInfo.add(procedure.agentClassString)
+            // args contains dummies (temp 'lets') so we don't include them.
+            // localsCount contains number of lets so we just subtract that
+            val argsCount = procedure.args.size - procedure.localsCount
+            val args = procedure.args.take(argsCount).toLogoList
+            procedureInfo.add(args)
+            procedureInfo.toLogoList
+        }.toVector.toLogoList
+      }
+      case _ => throw new ExtensionException(s"Unknown context given : $context")
+    }
+  }
+}
+
+class CurrentProcedure extends Reporter {
+  override def getSyntax = Syntax.reporterSyntax(ret = ListType)
+  override def report(args: Array[Argument], context: Context): AnyRef = {
+    context match {
+      case extContext: ExtensionContext => extContext.nvmContext.activation.procedure.name;
+      case _ => throw new ExtensionException(s"Unknown context given : $context")
+    }
+  }
+}
+
+class Callers extends Reporter {
+  override def getSyntax = Syntax.reporterSyntax(ret = ListType)
+  override def report(args: Array[Argument], context: Context): AnyRef = {
+    val callers = new LogoListBuilder
+    context match {
+      case extContext: ExtensionContext => {
+        var activation = extContext.nvmContext.activation
+        while (activation != null && activation.procedure != null) {
+          callers.add(activation.procedure.name)
+          activation = activation.parent
+        }
+        callers.toLogoList
+      }
+      case _ => throw new ExtensionException(s"Unknown context given : $context")
+    }
+  }
+}

+ 5 - 0
debugging_environment/NetLogo/Reflection-Extension/src/test/Tests.scala

@@ -0,0 +1,5 @@
+package org.nlogo.extensions.reflection
+
+import org.nlogo.headless.TestLanguage
+
+class Tests extends TestLanguage(Seq(new java.io.File("tests.txt").getCanonicalFile))

+ 57 - 0
debugging_environment/NetLogo/Reflection-Extension/tests.txt

@@ -0,0 +1,57 @@
+reflection-gets-globals-when-none-defined
+  extensions [ reflection ]
+  globals [ ]
+  breed [ cars car ]
+  turtles-own [ turt1 ]
+  cars-own [ cars1 ]
+  reflection:globals => []
+
+
+reflection-gets-globals
+  extensions [ reflection ]
+  globals [ glob1 ]
+  breed [ cars car ]
+  turtles-own [ turt1 ]
+  cars-own [ cars1 ]
+  reflection:globals => ["GLOB1"]
+
+reflection-gets-breeds-works-with-no-custom-defined
+  extensions [ reflection ]
+  globals [ glob1 ]
+  turtles-own [ turt1 ]
+  reflection:breeds => [["TURTLES" ["WHO" "COLOR" "HEADING" "XCOR" "YCOR" "SHAPE" "LABEL" "LABEL-COLOR" "BREED" "HIDDEN?" "SIZE" "PEN-SIZE" "PEN-MODE" "TURT1"]]]
+
+reflection-gets-breeds-works-with-custom
+  extensions [ reflection ]
+  globals [ glob1 ]
+  breed [ cars car ]
+  breed [ vans van ]
+  turtles-own [ turt1 ]
+  cars-own [ cars1 ]
+  reflection:breeds => [["TURTLES" ["WHO" "COLOR" "HEADING" "XCOR" "YCOR" "SHAPE" "LABEL" "LABEL-COLOR" "BREED" "HIDDEN?" "SIZE" "PEN-SIZE" "PEN-MODE" "TURT1"]] ["CARS" ["CARS1"]] ["VANS" []]]
+
+reflection-gets-procedures-works-when-none-defined
+  extensions [ reflection ]
+  reflection:procedures => []
+
+reflection-gets-procedures
+  extensions [ reflection ]
+  to-report rev [tacos] report (tacos - 1) end
+  to start let vs 0 show vs end
+  reflection:procedures => [["REV" "REPORTER" "OTPL" ["TACOS"]] ["START" "COMMAND" "OTPL" []]]
+
+reflection-gets-current-procedure
+  extensions [ reflection ]
+  to-report rev [tacos] set tacos (tacos - 1) report reflection:current-procedure end
+  to start let vs 0 show vs end
+  rev 10 => "REV"
+
+*reflection-gets-current-procedure-works-from-command
+  extensions [ reflection ]
+  reflection:current-procedure => "__EVALUATOR"
+
+*reflection-gets-callers
+  extensions [ reflection ]
+  to-report rev [tacos] set tacos (tacos - 1) report reflection:callers end
+  to start let vs 0 show vs end
+  rev 10 => ["REV" "__EVALUATOR"]