Skip to content

Commit

Permalink
Saves all files so that modules can be imported; bug fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Tobias-Kohn committed Sep 30, 2020
1 parent ad597ea commit 0251e65
Show file tree
Hide file tree
Showing 18 changed files with 129 additions and 34 deletions.
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
# Changelog


### 3.0 Early Access Preview 7 (.. September 2020)
### 3.0 Early Access Preview 7 (30 September 2020)

Implemented:
- Can delete files from the '+' tab;
- TigerJython executor instances are started ahead of time for faster response;
- Saves all documents so that they can be mutually imported;

Changes:
- Import of files from disk is more prominent and visible;

Bug fixes:
- Loads previously created files;
- All threads and running executor instances are shutdown when closing the app;
- Runtime errors are actually displayed;

Known issues:
- Errors in modules are not displayed at the correct position;


### 3.0 Early Access Preview 6 (25 September 2020)
Expand Down
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@

TigerJython is an educational development environment for Python with enhanced error messages. It runs on the Java
Virtual Machine and already includes [Jython](https://www.jython.org/). If you have JRE installed, just download
the [JAR-file](https://github.com/Tiger-Jython/TigerJython/releases/download/v3.0-ea%2B6/TigerJython3-ea+6.jar) under
the [JAR-file](https://github.com/Tiger-Jython/TigerJython/releases/download/v3.0-ea%2B7/TigerJython3-ea+7.jar) under
[**release**](https://github.com/Tiger-Jython/TigerJython/releases/latest).

> This is an early access version that is not yet ready for classroom use!!!
**!!! Please note that TigerJython will manipulate and rewrite any files you open with it. We strongly advise that you back up your files before accessing them with the TigerJython preview !!!**

**Several features are not yet working, including syntax highlighting—there is no sense in raising issue tickets
at the moment, as we are constantly working on the IDE.**

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import java.nio.file.Path
* @author Tobias Kohn
*/
class CommandExecutorFactory(val name: String,
val cmd: Path) extends ExecutorFactory {
val cmd: Path,
val execLanguage: ExecLanguage.Value) extends ExecutorFactory {

def createEvaluator(controller: ExecutionController, onReady: Evaluator=>Unit): Unit = {
val evaluator = new ProcessEvaluator(new InteractiveOSProcess(getCommand))
Expand All @@ -26,4 +27,6 @@ class CommandExecutorFactory(val name: String,
}

protected def getCommand: String = cmd.toAbsolutePath.toString

def getExecLanguage: ExecLanguage.Value = execLanguage
}
24 changes: 24 additions & 0 deletions src/main/scala/tigerjython/execute/ExecLanguage.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* This file is part of the 'TigerJython' project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package tigerjython.execute

/**
* @author Tobias Kohn
*/
object ExecLanguage extends Enumeration {

final val PYTHON_2 = Value

final val PYTHON_3 = Value

def python(version: Int): Value =
version match {
case 2 => PYTHON_2
case _ => PYTHON_3
}
}
3 changes: 3 additions & 0 deletions src/main/scala/tigerjython/execute/ExecutionController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ trait ExecutionController {

def getExecutableFile: File

def handleError(errorText: String): Unit =
appendToErrorOutput(errorText)

def notifyExecutionFinished(executionTime: Long, terminated: Boolean = false): Unit =
if (terminated) {
appendToLog("process terminated after %d ms".format(executionTime))
Expand Down
2 changes: 2 additions & 0 deletions src/main/scala/tigerjython/execute/ExecutorFactory.scala
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ trait ExecutorFactory {

def createExecutor(controller: ExecutionController, onReady: Executor=>Unit): Unit

def getExecLanguage: ExecLanguage.Value

def name: String

def shutdown(): Unit = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,18 @@ object InterpreterInstallations {
case "tigerjython" =>
result += InterpreterInfo(name, ImagePool.tigerJython_Logo, TigerJythonExecutorFactory)
case "jython" =>
val factory = new CommandExecutorFactory(name, path)
val factory = new CommandExecutorFactory(name, path, ExecLanguage.python(version))
interpreters += InterpreterInfo(name, ImagePool.jython_Logo, factory)
case "pypy" =>
val factory = new CommandExecutorFactory(name, path)
val factory = new CommandExecutorFactory(name, path, ExecLanguage.python(version))
interpreters += InterpreterInfo(name, ImagePool.pypy_Logo, factory)
case "python" =>
val factory = new CommandExecutorFactory(name, path)
if (version < 3)
interpreters += InterpreterInfo(name, ImagePool.python2_Logo, factory)
interpreters += InterpreterInfo(name, ImagePool.python2_Logo,
new CommandExecutorFactory(name, path, ExecLanguage.PYTHON_2))
else
interpreters += InterpreterInfo(name, ImagePool.python_Logo, factory)
interpreters += InterpreterInfo(name, ImagePool.python_Logo,
new CommandExecutorFactory(name, path, ExecLanguage.PYTHON_3))
case _ =>
}
if (result.nonEmpty)
Expand Down
17 changes: 12 additions & 5 deletions src/main/scala/tigerjython/execute/PythonCodeTranslator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,22 @@ object PythonCodeTranslator {
* @param code The source code as a `String` value.
* @return Either `None` or a new `String` representing the transformed code.
*/
def translate(code: String): Option[String] = {
def translate(code: String, execLanguage: ExecLanguage.Value): Option[String] = {
if (Preferences.repeatLoop.get)
_translate(code)
execLanguage match {
case ExecLanguage.PYTHON_2 =>
_translate(code, 2)
case ExecLanguage.PYTHON_3 =>
_translate(code, 3)
case _ =>
None
}
else
None
}

protected def _translate(code: String): Option[String] = {
val parserState = ParserState(code, 3, ErrorHandler.SilentErrorHandler)
protected def _translate(code: String, pythonVersion: Int): Option[String] = {
val parserState = ParserState(code, pythonVersion, ErrorHandler.SilentErrorHandler)
parserState.repeatStatement = Preferences.repeatLoop.get
val lexer = new Lexer(code, parserState, 0)
val result = new StringBuilder()
Expand Down Expand Up @@ -63,7 +70,7 @@ object PythonCodeTranslator {
val hd = lexer.head
if (hd != null) {
val argument = code.substring(position, hd.pos)
result ++= REPEAT_STRING(3).format(argument)
result ++= REPEAT_STRING(pythonVersion).format(argument)
position = hd.pos
}
} else
Expand Down
4 changes: 3 additions & 1 deletion src/main/scala/tigerjython/execute/TigerJythonExecutor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,12 @@ class TigerJythonExecutor(val id: Int, override val controller: ExecutionControl
controller.notifyExecutionStarted()
controller.updateRunStatus(this, running = true)
val startTime = System.currentTimeMillis()
proxy.executeFile(filename, (_, _) => {
proxy.executeFile(filename, (msg, isError) => {
val runTime = System.currentTimeMillis() - startTime
proxy.sendMessage(QuitMessage())
Thread.sleep(250) // Leave some time for the output to appear in the editor window
if (isError)
controller.handleError(msg)
controller.notifyExecutionFinished(runTime)
})
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,6 @@ object TigerJythonExecutorFactory extends ExecutorFactory {
def createExecutor(controller: ExecutionController, onReady: Executor=>Unit): Unit = {
onReady(newInstance(controller))
}

def getExecLanguage: ExecLanguage.Value = ExecLanguage.PYTHON_2
}
28 changes: 22 additions & 6 deletions src/main/scala/tigerjython/files/Document.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/
package tigerjython.files

import java.io.{FileWriter, PrintWriter}
import java.io.{File, FileWriter, PrintWriter}
import java.nio.file.attribute.BasicFileAttributes
import java.nio.file.{Files, Path, Paths}
import java.text.{DateFormat, SimpleDateFormat}
Expand All @@ -16,7 +16,7 @@ import java.util.Date
import java.util.prefs.{Preferences => JPreferences}

import javafx.beans.property._
import tigerjython.execute.PythonCodeTranslator
import tigerjython.execute.{ExecLanguage, PythonCodeTranslator}
import tigerjython.ui.{TabFrame, TigerJythonApplication}
import tigerjython.utils._

Expand Down Expand Up @@ -95,29 +95,41 @@ class Document(protected val prefNode: JPreferences) {
new SimpleDateFormat("d MMM").format(getCreationDate),
formatDate(lastModified)
)
else
else if (d1.getDayOfMonth != d2.getDayOfMonth)
"%d–%s".format(d1.getDayOfMonth, formatDate(lastModified))
else
formatDate(lastModified)
} else
"%s–%s".format(formatDate(getCreationDate), formatDate(lastModified))
}

def getDefaultFileSuffix: String = ".py"

private def createTempFile(): java.io.File =
new File(Documents.tempDir, name.getValue
.replace('?', '_').replace('*', '_').replace('&', '_')
.replace('/', '_').replace('\\', '_').replace('\"', '_') +
getDefaultFileSuffix)
/*java.io.File.createTempFile(name.getValue
.replace('?', '_').replace('*', '_').replace('&', '_')
.replace('/', '_').replace('\\', '_').replace('\"', '_') +
" (", ")" + getDefaultFileSuffix)*/

/**
* Creates a temporary file for execution, even if the document does otherwise not have an actual file backing it
* up.
*/
def getExecutableFile: java.io.File = {
def getExecutableFile(execLanguage: ExecLanguage.Value): java.io.File = {
var result = file
if (result == null) {
if (_tempFile == null) {
_tempFile = java.io.File.createTempFile(name.getValue + " (", ")" + getDefaultFileSuffix)
_tempFile = createTempFile()
_tempFile.deleteOnExit()
}
result = _tempFile
}
val text =
PythonCodeTranslator.translate(this.text.get) match {
PythonCodeTranslator.translate(this.text.get, execLanguage) match {
case Some(text) =>
text
case None =>
Expand All @@ -132,6 +144,10 @@ class Document(protected val prefNode: JPreferences) {
result
}

def saveExecutableFile(execLanguage: ExecLanguage.Value): Unit = {
getExecutableFile(execLanguage)
}

def getSearchScore(filter: SearchFilter): Int =
filter.getScore(name.get) + filter.getScore(description.get) +
filter.getScore(text.get) + filter.getScore(pathString.get())
Expand Down
11 changes: 11 additions & 0 deletions src/main/scala/tigerjython/files/Documents.scala
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package tigerjython.files

import java.io.File
import java.nio.file.Path
import java.util.prefs.{Preferences => JPreferences}

import sun.security.action.GetPropertyAction
import tigerjython.execute.ExecLanguage
import tigerjython.ui.{TigerJythonApplication, editor}

/**
Expand Down Expand Up @@ -79,6 +82,9 @@ object Documents {
result
}

lazy val tempDir: File =
new File(GetPropertyAction.privilegedGetProperty("java.io.tmpdir"))

private[files]
def removeDocument(document: Document): Unit = {
val idx = documents.indexOf(document)
Expand All @@ -100,6 +106,11 @@ object Documents {
n
}

def saveAllExecutables(execLanguage: ExecLanguage.Value): Unit = {
for (document <- documents)
document.saveExecutableFile(execLanguage)
}

/**
* Reads all the documents from the preferences.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import java.net.Socket
import java.util.{Timer, TimerTask}
import java.util.concurrent.ArrayBlockingQueue

import org.python.core.{CodeFlag, CompileMode, CompilerFlags, Py, PyObject}
import org.python.core.{CodeFlag, CompileMode, CompilerFlags, Py, PyList, PyObject}
import org.python.util.PythonInterpreter
import tigerjython.core.Configuration

Expand Down Expand Up @@ -104,6 +104,13 @@ object ExecuteClientConnection extends Communicator {
val task = new SystemInfoReporter()
try {
timer.schedule(task, 0, 100)
interpreter.getSystemState.path match {
case lst: PyList =>
val s = Py.newString(new java.io.File(filename).getParent)
if (!lst.__contains__(s))
lst.append(s)
case _ =>
}
interpreter.execfile(filename)
sendMessage(ResultMessage(null, tag))
} catch {
Expand Down
3 changes: 2 additions & 1 deletion src/main/scala/tigerjython/remote/ExecuteClientProxy.scala
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,11 @@ class ExecuteClientProxy(val socket: Socket) extends Communicator {
case QuitMessage() =>
ExecuteServer.removeClient(this)
case ErrorResultMessage(errorMsg, tag) =>
queryBuffer.remove(tag) match {
queryBuffer.get(tag) match {
case Some(onResult) =>
onResult(errorMsg, true)
case None =>
println(errorMsg)
}
case ResultMessage(result, tag) =>
queryBuffer.remove(tag) match {
Expand Down
3 changes: 2 additions & 1 deletion src/main/scala/tigerjython/ui/TigerJythonApplication.scala
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@ class TigerJythonApplication extends Application {
editing.SyntaxHighlighter.shutdown()
editing.BackgroundSaver.shutdown()
Platform.exit()
//sys.exit()
Thread.sleep(500)
sys.exit()
}

def showPreferences(): Unit = {
Expand Down
20 changes: 14 additions & 6 deletions src/main/scala/tigerjython/ui/editor/EditorTab.scala
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,11 @@ abstract class EditorTab extends TabFrame with ExecutionController {
appendToLog("ERROR in line %d".format(line+1))
appendToLog(msg)
editor.requestFocus()
editor.moveTo(line, column)
try {
editor.moveTo(line, column)
} catch {
case _: IndexOutOfBoundsException =>
}
val caretBounds = editor.caretBoundsProperty().getValue
if (caretBounds.isPresent) {
val popup = new Popup()
Expand Down Expand Up @@ -293,17 +297,21 @@ abstract class EditorTab extends TabFrame with ExecutionController {
editor.requestFocus()
})
})
else
else {
hideError()
autoSave()
}
}

def getCaretPosition: Int =
editor.getCaretPosition

def getExecutableFile: java.io.File =
if (document != null)
document.getExecutableFile
else
if (document != null && execFactory != null) {
val execLanguage = execFactory.getExecLanguage
Documents.saveAllExecutables(execLanguage)
document.getExecutableFile(execLanguage)
} else
null

def getFile: java.io.File = file
Expand All @@ -314,7 +322,7 @@ abstract class EditorTab extends TabFrame with ExecutionController {
def getText: String =
editor.getText

def handleError(errorText: String): Unit = {
override def handleError(errorText: String): Unit = {
infoPane.getSelectionModel.select(1)
val (line, filename, msg) = PythonRuntimeErrors.generateMessage(errorText)
if (line >= 0 && msg != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class ImportDocumentItem(val parentFrame: OpenDocumentTab) extends DocumentItem

{
titleLabel.setText("Import/Open Document")
descriptionLabel.setText("Load a document from a file on disc")
descriptionLabel.setText("Load a document from a file on disk")
}

protected lazy val fileChooser: FileChooser = {
Expand Down
Loading

0 comments on commit 0251e65

Please sign in to comment.