mirror of
https://github.com/processing/processing4.git
synced 2026-02-03 21:59:20 +01:00
Merge branch 'master' into static_imports
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2012-15 The Processing Foundation
|
||||
Copyright (c) 2012-19 The Processing Foundation
|
||||
Copyright (c) 2008-12 Ben Fry and Casey Reas
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
@@ -42,8 +42,6 @@ import processing.mode.java.runner.Runner;
|
||||
|
||||
/**
|
||||
* Class to handle running Processing from the command line.
|
||||
*
|
||||
* @author fry
|
||||
*/
|
||||
public class Commander implements RunnerListener {
|
||||
static final String helpArg = "--help";
|
||||
@@ -65,7 +63,6 @@ public class Commander implements RunnerListener {
|
||||
static final int BUILD = 1;
|
||||
static final int RUN = 2;
|
||||
static final int PRESENT = 3;
|
||||
// static final int EXPORT_APPLET = 4;
|
||||
static final int EXPORT = 4;
|
||||
|
||||
Sketch sketch;
|
||||
@@ -74,19 +71,6 @@ public class Commander implements RunnerListener {
|
||||
PrintStream systemErr;
|
||||
|
||||
|
||||
static public void main(String[] args) {
|
||||
// Do this early so that error messages go to the console
|
||||
Base.setCommandLine();
|
||||
// init the platform so that prefs and other native code is ready to go
|
||||
Platform.init();
|
||||
// make sure a full JDK is installed
|
||||
//Base.initRequirements();
|
||||
|
||||
// launch command line handler
|
||||
new Commander(args);
|
||||
}
|
||||
|
||||
|
||||
public Commander(String[] args) {
|
||||
String sketchPath = null;
|
||||
File sketchFolder = null;
|
||||
@@ -152,7 +136,6 @@ public class Commander implements RunnerListener {
|
||||
embedJava = false;
|
||||
|
||||
} else if (arg.startsWith(platformArg)) {
|
||||
// complainAndQuit("The --platform option has been removed from Processing 2.1.", false);
|
||||
String platformStr = arg.substring(platformArg.length());
|
||||
platform = Platform.getIndex(platformStr);
|
||||
if (platform == -1) {
|
||||
@@ -160,17 +143,6 @@ public class Commander implements RunnerListener {
|
||||
"'windows', 'macosx', or 'linux'.", true);
|
||||
}
|
||||
|
||||
} else if (arg.startsWith(bitsArg)) {
|
||||
complainAndQuit("The --bits option has been removed.", false);
|
||||
// String bitsStr = arg.substring(bitsArg.length());
|
||||
// if (bitsStr.equals("32")) {
|
||||
// platformBits = 32;
|
||||
// } else if (bitsStr.equals("64")) {
|
||||
// platformBits = 64;
|
||||
// } else {
|
||||
// complainAndQuit("Bits should be either 32 or 64, not " + bitsStr, true);
|
||||
// }
|
||||
|
||||
} else if (arg.startsWith(sketchArg)) {
|
||||
sketchPath = arg.substring(sketchArg.length());
|
||||
sketchFolder = new File(sketchPath);
|
||||
@@ -199,13 +171,6 @@ public class Commander implements RunnerListener {
|
||||
}
|
||||
String[] sketchArgs = PApplet.subset(args, argOffset);
|
||||
|
||||
// if ((outputPath == null) &&
|
||||
// (task == PREPROCESS || task == BUILD ||
|
||||
// task == RUN || task == PRESENT)) {
|
||||
// complainAndQuit("An output path must be specified when using " +
|
||||
// preprocArg + ", " + buildArg + ", " +
|
||||
// runArg + ", or " + presentArg + ".");
|
||||
// }
|
||||
if (task == HELP) {
|
||||
printCommandLine(systemOut);
|
||||
System.exit(0);
|
||||
@@ -256,8 +221,6 @@ public class Commander implements RunnerListener {
|
||||
|
||||
boolean success = false;
|
||||
|
||||
// JavaMode javaMode =
|
||||
// new JavaMode(null, Base.getContentFile("modes/java"));
|
||||
JavaMode javaMode = (JavaMode)
|
||||
ModeContribution.load(null, Platform.getContentFile("modes/java"),
|
||||
"processing.mode.java.JavaMode").getMode();
|
||||
@@ -389,9 +352,6 @@ public class Commander implements RunnerListener {
|
||||
out.println("--no-java Do not embed Java. Use at your own risk!");
|
||||
out.println("--platform Specify the platform (export to application only).");
|
||||
out.println(" Should be one of 'windows', 'macosx', or 'linux'.");
|
||||
// out.println("--bits Must be specified if libraries are used that are");
|
||||
// out.println(" 32- or 64-bit specific such as the OpenGL library.");
|
||||
// out.println(" Otherwise specify 0 or leave it out.");
|
||||
|
||||
out.println();
|
||||
out.println("The --build, --run, --present, or --export must be the final parameter");
|
||||
@@ -406,22 +366,31 @@ public class Commander implements RunnerListener {
|
||||
|
||||
|
||||
@Override
|
||||
public void startIndeterminate() {
|
||||
}
|
||||
public void startIndeterminate() { }
|
||||
|
||||
|
||||
@Override
|
||||
public void stopIndeterminate() {
|
||||
}
|
||||
public void stopIndeterminate() { }
|
||||
|
||||
|
||||
@Override
|
||||
public void statusHalt() {
|
||||
}
|
||||
public void statusHalt() { }
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isHalted() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static public void main(String[] args) {
|
||||
// Do this early so that error messages go to the console
|
||||
Base.setCommandLine();
|
||||
|
||||
// init the platform so that prefs and other native code is ready to go
|
||||
Platform.init();
|
||||
|
||||
// launch command line handler
|
||||
new Commander(args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,9 +31,6 @@ import java.io.*;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
|
||||
//import org.eclipse.jdt.core.compiler.batch.BatchCompiler;
|
||||
//import org.eclipse.jdt.core.compiler.CompilationProgress;
|
||||
|
||||
|
||||
public class Compiler {
|
||||
|
||||
|
||||
@@ -139,7 +139,8 @@ public class JavaBuild {
|
||||
* @return null if compilation failed, main class name if not
|
||||
*/
|
||||
public String preprocess(File srcFolder, boolean sizeWarning) throws SketchException {
|
||||
return preprocess(srcFolder, null, new PdePreprocessor(sketch.getName()), sizeWarning);
|
||||
PdePreprocessor preprocessor = PdePreprocessor.builderFor(sketch.getName()).build();
|
||||
return preprocess(srcFolder, null, preprocessor, sizeWarning);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,26 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2012-19 The Processing Foundation
|
||||
Copyright (c) 2004-12 Ben Fry and Casey Reas
|
||||
Copyright (c) 2001-04 Massachusetts Institute of Technology
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.mode.java;
|
||||
|
||||
import java.awt.*;
|
||||
@@ -125,7 +148,7 @@ public class JavaEditor extends Editor {
|
||||
|
||||
|
||||
public PdePreprocessor createPreprocessor(final String sketchName) {
|
||||
return new PdePreprocessor(sketchName);
|
||||
return PdePreprocessor.builderFor(sketchName).build();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2012-15 The Processing Foundation
|
||||
Copyright (c) 2012-19 The Processing Foundation
|
||||
Copyright (c) 2004-12 Ben Fry and Casey Reas
|
||||
Copyright (c) 2001-04 Massachusetts Institute of Technology
|
||||
|
||||
@@ -24,15 +24,15 @@
|
||||
|
||||
package processing.mode.java;
|
||||
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.Arrays;
|
||||
|
||||
import processing.app.Preferences;
|
||||
import processing.app.Sketch;
|
||||
import processing.app.syntax.*;
|
||||
import processing.app.syntax.JEditTextArea;
|
||||
import processing.app.syntax.PdeInputHandler;
|
||||
import processing.app.ui.Editor;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.Arrays;
|
||||
|
||||
|
||||
/**
|
||||
* Filters key events for tab expansion/indent/etc. This is very old code
|
||||
@@ -41,9 +41,9 @@ import java.util.Arrays;
|
||||
*/
|
||||
public class JavaInputHandler extends PdeInputHandler {
|
||||
|
||||
/** ctrl-alt on windows and linux, cmd-alt on mac os x */
|
||||
static final int CTRL_ALT = ActionEvent.ALT_MASK |
|
||||
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
|
||||
// /** ctrl-alt on windows and linux, cmd-alt on mac os x */
|
||||
// static final int CTRL_ALT = ActionEvent.ALT_MASK |
|
||||
// Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
|
||||
|
||||
|
||||
public JavaInputHandler(Editor editor) {
|
||||
@@ -66,7 +66,8 @@ public class JavaInputHandler extends PdeInputHandler {
|
||||
Sketch sketch = editor.getSketch();
|
||||
JEditTextArea textarea = editor.getTextArea();
|
||||
|
||||
if ((event.getModifiers() & InputEvent.META_MASK) != 0) {
|
||||
if (event.isMetaDown()) {
|
||||
//if ((event.getModifiers() & InputEvent.META_MASK) != 0) {
|
||||
//event.consume(); // does nothing
|
||||
return false;
|
||||
}
|
||||
@@ -76,8 +77,8 @@ public class JavaInputHandler extends PdeInputHandler {
|
||||
sketch.setModified(true);
|
||||
}
|
||||
|
||||
if ((code == KeyEvent.VK_UP) &&
|
||||
((event.getModifiers() & InputEvent.CTRL_MASK) != 0)) {
|
||||
if ((code == KeyEvent.VK_UP) && event.isControlDown()) {
|
||||
//((event.getModifiers() & InputEvent.CTRL_MASK) != 0)) {
|
||||
// back up to the last empty line
|
||||
char contents[] = textarea.getText().toCharArray();
|
||||
//int origIndex = textarea.getCaretPosition() - 1;
|
||||
@@ -104,7 +105,8 @@ public class JavaInputHandler extends PdeInputHandler {
|
||||
// if the first char, index will be -2
|
||||
if (index < 0) index = 0;
|
||||
|
||||
if ((event.getModifiers() & InputEvent.SHIFT_MASK) != 0) {
|
||||
//if ((event.getModifiers() & InputEvent.SHIFT_MASK) != 0) {
|
||||
if (event.isShiftDown()) {
|
||||
textarea.setSelectionStart(caretIndex);
|
||||
textarea.setSelectionEnd(index);
|
||||
} else {
|
||||
@@ -113,8 +115,8 @@ public class JavaInputHandler extends PdeInputHandler {
|
||||
event.consume();
|
||||
// return true;
|
||||
|
||||
} else if ((code == KeyEvent.VK_DOWN) &&
|
||||
((event.getModifiers() & InputEvent.CTRL_MASK) != 0)) {
|
||||
} else if ((code == KeyEvent.VK_DOWN) && event.isControlDown()) {
|
||||
//((event.getModifiers() & InputEvent.CTRL_MASK) != 0)) {
|
||||
char contents[] = textarea.getText().toCharArray();
|
||||
int caretIndex = textarea.getCaretPosition();
|
||||
|
||||
@@ -136,7 +138,8 @@ public class JavaInputHandler extends PdeInputHandler {
|
||||
index++;
|
||||
}
|
||||
|
||||
if ((event.getModifiers() & InputEvent.SHIFT_MASK) != 0) {
|
||||
//if ((event.getModifiers() & InputEvent.SHIFT_MASK) != 0) {
|
||||
if (event.isShiftDown()) {
|
||||
textarea.setSelectionStart(caretIndex);
|
||||
textarea.setSelectionEnd(index);
|
||||
} else {
|
||||
@@ -146,7 +149,8 @@ public class JavaInputHandler extends PdeInputHandler {
|
||||
// return true;
|
||||
|
||||
} else if (c == 9) {
|
||||
if ((event.getModifiers() & InputEvent.SHIFT_MASK) != 0) {
|
||||
//if ((event.getModifiers() & InputEvent.SHIFT_MASK) != 0) {
|
||||
if (event.isShiftDown()) {
|
||||
// if shift is down, the user always expects an outdent
|
||||
// http://code.google.com/p/processing/issues/detail?id=458
|
||||
editor.handleOutdent();
|
||||
@@ -317,7 +321,8 @@ public class JavaInputHandler extends PdeInputHandler {
|
||||
public boolean handleTyped(KeyEvent event) {
|
||||
char c = event.getKeyChar();
|
||||
|
||||
if ((event.getModifiers() & InputEvent.CTRL_MASK) != 0) {
|
||||
//if ((event.getModifiers() & InputEvent.CTRL_MASK) != 0) {
|
||||
if (event.isControlDown()) { // TODO true on typed? [fry 191007]
|
||||
// on linux, ctrl-comma (prefs) being passed through to the editor
|
||||
if (c == KeyEvent.VK_COMMA) {
|
||||
event.consume();
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2010-11 Ben Fry and Casey Reas
|
||||
Copyright (c) 2012-15 The Processing Foundation
|
||||
Copyright (c) 2012-19 The Processing Foundation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
@@ -37,6 +37,7 @@ import processing.app.*;
|
||||
import processing.app.ui.Editor;
|
||||
import processing.app.ui.EditorException;
|
||||
import processing.app.ui.EditorState;
|
||||
|
||||
import processing.mode.java.runner.Runner;
|
||||
import processing.mode.java.tweak.SketchParser;
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
package processing.mode.java;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -131,7 +130,7 @@ public class JavaToolbar extends EditorToolbar {
|
||||
|
||||
@Override
|
||||
public void handleRun(int modifiers) {
|
||||
boolean shift = (modifiers & InputEvent.SHIFT_MASK) != 0;
|
||||
boolean shift = (modifiers & ActionEvent.SHIFT_MASK) != 0;
|
||||
if (shift) {
|
||||
jeditor.handlePresent();
|
||||
} else {
|
||||
|
||||
@@ -1790,7 +1790,7 @@ public class CompletionGenerator {
|
||||
|
||||
// Now parse the expression into an ASTNode object
|
||||
ASTNode nearestNode;
|
||||
ASTParser parser = ASTParser.newParser(AST.JLS8);
|
||||
ASTParser parser = ASTParser.newParser(AST.JLS11);
|
||||
parser.setKind(ASTParser.K_EXPRESSION);
|
||||
parser.setSource(phrase.toCharArray());
|
||||
ASTNode testnode = parser.createAST(null);
|
||||
|
||||
@@ -52,7 +52,6 @@ import processing.mode.java.pdex.util.ProblemFactory;
|
||||
import processing.mode.java.pdex.util.RuntimePathBuilder;
|
||||
import processing.mode.java.preproc.PdePreprocessor;
|
||||
import processing.mode.java.preproc.PreprocessorResult;
|
||||
import processing.mode.java.preproc.code.ImportUtil;
|
||||
import processing.mode.java.preproc.code.SyntaxUtil;
|
||||
|
||||
|
||||
@@ -522,16 +521,16 @@ public class PreprocessingService {
|
||||
/**
|
||||
* Determine which imports need to be available for core processing services.
|
||||
*
|
||||
* @param p The preprocessor to operate on.
|
||||
* @param preprocessor The preprocessor to operate on.
|
||||
* @return The import statements that need to be present.
|
||||
*/
|
||||
private static List<ImportStatement> buildCoreAndDefaultImports(PdePreprocessor p) {
|
||||
private static List<ImportStatement> buildCoreAndDefaultImports(PdePreprocessor preprocessor) {
|
||||
List<ImportStatement> result = new ArrayList<>();
|
||||
|
||||
for (String imp : ImportUtil.getCoreImports()) {
|
||||
for (String imp : preprocessor.getCoreImports()) {
|
||||
result.add(ImportStatement.parse(imp));
|
||||
}
|
||||
for (String imp : ImportUtil.getDefaultImports()) {
|
||||
for (String imp : preprocessor.getDefaultImports()) {
|
||||
result.add(ImportStatement.parse(imp));
|
||||
}
|
||||
|
||||
|
||||
@@ -20,22 +20,31 @@ along with this program; if not, write to the Free Software Foundation, Inc.
|
||||
|
||||
package processing.mode.java.pdex.util;
|
||||
|
||||
import com.google.classpath.ClassPathFactory;
|
||||
import processing.app.*;
|
||||
import processing.mode.java.JavaMode;
|
||||
import processing.mode.java.pdex.ImportStatement;
|
||||
import processing.mode.java.pdex.PreprocessedSketch;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.google.classpath.ClassPathFactory;
|
||||
|
||||
import processing.app.Library;
|
||||
import processing.app.Messages;
|
||||
import processing.app.Sketch;
|
||||
import processing.app.SketchException;
|
||||
import processing.app.Util;
|
||||
import processing.mode.java.JavaMode;
|
||||
import processing.mode.java.pdex.ImportStatement;
|
||||
import processing.mode.java.pdex.PreprocessedSketch;
|
||||
|
||||
|
||||
/**
|
||||
* Builder which generates runtime paths using a series of caches.
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2012-19 The Processing Foundation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.mode.java.preproc;
|
||||
|
||||
import processing.mode.java.preproc.issue.PdePreprocessIssue;
|
||||
|
||||
|
||||
/**
|
||||
* Listener for issues encountered while processing a valid pde parse tree.
|
||||
*/
|
||||
interface PdeParseTreeErrorListener {
|
||||
|
||||
/**
|
||||
* Callback to invoke when an issue is encountered while processing a valid PDE parse tree.
|
||||
*
|
||||
* @param issue The issue reported.
|
||||
*/
|
||||
void onError(PdePreprocessIssue issue);
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -24,7 +24,9 @@ package processing.mode.java.preproc;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.antlr.v4.runtime.*;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
@@ -32,58 +34,92 @@ import org.antlr.v4.runtime.tree.ParseTreeWalker;
|
||||
|
||||
import processing.app.Preferences;
|
||||
import processing.app.SketchException;
|
||||
import processing.mode.java.preproc.code.ImportUtil;
|
||||
import processing.mode.java.preproc.issue.PdeIssueEmitter;
|
||||
import processing.mode.java.preproc.issue.PdePreprocessIssue;
|
||||
|
||||
|
||||
/**
|
||||
* Utility to preprocess sketches prior to comilation.
|
||||
* Utility to preprocess sketches prior to compilation.
|
||||
*
|
||||
* <p>
|
||||
* This preprocessor assists with
|
||||
* </p>
|
||||
*/
|
||||
public class PdePreprocessor {
|
||||
|
||||
/**
|
||||
* The mode that the sketch uses to run.
|
||||
*/
|
||||
public static enum Mode {
|
||||
STATIC, ACTIVE, JAVA
|
||||
/**
|
||||
* Sketch without draw, setup, or settings functions where code is run as if the body of a
|
||||
* method without any enclosing types. This code will not define its enclosing class or method.
|
||||
*/
|
||||
STATIC,
|
||||
|
||||
/**
|
||||
* Sketch using draw, setup, and / or settings where the code is run as if defining the body
|
||||
* of a class. This code will not define its enclosing class but it will define its enclosing
|
||||
* method.
|
||||
*/
|
||||
ACTIVE,
|
||||
|
||||
/**
|
||||
* Sketch written like typical Java where the code is run such that it defines the enclosing
|
||||
* classes itself.
|
||||
*/
|
||||
JAVA
|
||||
}
|
||||
|
||||
private String sketchName;
|
||||
private int tabSize;
|
||||
|
||||
private boolean hasMain;
|
||||
|
||||
private final String sketchName;
|
||||
private final int tabSize;
|
||||
private final boolean isTesting;
|
||||
private final ParseTreeListenerFactory listenerFactory;
|
||||
private final List<String> defaultImports;
|
||||
private final List<String> coreImports;
|
||||
private final Optional<String> destinationPackage;
|
||||
|
||||
private boolean foundMain;
|
||||
|
||||
/**
|
||||
* Create a new preprocessor.
|
||||
* Create a new PdePreprocessorBuilder for a sketch of the given name.
|
||||
*
|
||||
* @param sketchName The name of the sketch.
|
||||
* Create a new builder to help instantiate a preprocessor for a sketch of the given name. Use
|
||||
* this builder to configure settings of the preprocessor before building.
|
||||
*
|
||||
* @param sketchName The name of the sketch for which a preprocessor will be built.
|
||||
* @return Builder to create a preprocessor for the sketch of the given name.
|
||||
*/
|
||||
public PdePreprocessor(final String sketchName) {
|
||||
this(sketchName, Preferences.getInteger("editor.tabs.size"), false);
|
||||
public static PdePreprocessorBuilder builderFor(String sketchName) {
|
||||
return new PdePreprocessorBuilder(sketchName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new preprocessor.
|
||||
*
|
||||
* @param sketchName The name of the sketch.
|
||||
* @param tabSize The number of tabs.
|
||||
*/
|
||||
public PdePreprocessor(final String sketchName, final int tabSize) {
|
||||
this(sketchName, tabSize, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new preprocessor.
|
||||
* Create a new preprocessor that will use the following set of configuration values to process
|
||||
* a parse tree. This object can be instantiated by calling {builderFor}.
|
||||
*
|
||||
* @param sketchName The name of the sketch.
|
||||
* @param tabSize The number of tabs.
|
||||
* @param isTesting Flag indicating if this is running in unit tests (true) or in production
|
||||
* @param newSketchName The name of the sketch.
|
||||
* @param newTabSize The number of spaces within a tab.
|
||||
* @param newIsTesting Flag indicating if this is running in unit tests (true) or in production
|
||||
* (false).
|
||||
* @param newFactory The factory to use for building the ANTLR tree traversal listener where
|
||||
* preprocessing edits should be made.
|
||||
* @param newDefaultImports Imports provided for user convenience.
|
||||
* @param newCoreImports Imports required for core or processing itself.
|
||||
*/
|
||||
public PdePreprocessor(final String sketchName, final int tabSize, boolean isTesting) {
|
||||
this.sketchName = sketchName;
|
||||
this.tabSize = tabSize;
|
||||
this.isTesting = isTesting;
|
||||
public PdePreprocessor(final String newSketchName, final int newTabSize, boolean newIsTesting,
|
||||
final ParseTreeListenerFactory newFactory, List<String> newDefaultImports,
|
||||
List<String> newCoreImports, Optional<String> newDestinationPackage) {
|
||||
|
||||
sketchName = newSketchName;
|
||||
tabSize = newTabSize;
|
||||
isTesting = newIsTesting;
|
||||
listenerFactory = newFactory;
|
||||
defaultImports = newDefaultImports;
|
||||
coreImports = newCoreImports;
|
||||
destinationPackage = newDestinationPackage;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -151,10 +187,15 @@ public class PdePreprocessor {
|
||||
// Parser
|
||||
final List<PdePreprocessIssue> preprocessIssues = new ArrayList<>();
|
||||
final List<PdePreprocessIssue> treeIssues = new ArrayList<>();
|
||||
PdeParseTreeListener listener = createListener(tokens, sketchName);
|
||||
PdeParseTreeListener listener = listenerFactory.build(
|
||||
tokens,
|
||||
sketchName,
|
||||
tabSize,
|
||||
destinationPackage
|
||||
);
|
||||
listener.setTesting(isTesting);
|
||||
listener.setCoreImports(ImportUtil.getCoreImports());
|
||||
listener.setDefaultImports(ImportUtil.getDefaultImports());
|
||||
listener.setCoreImports(coreImports);
|
||||
listener.setDefaultImports(defaultImports);
|
||||
listener.setCodeFolderImports(codeFolderImports);
|
||||
listener.setTreeErrorListener((x) -> { treeIssues.add(x); });
|
||||
|
||||
@@ -188,7 +229,7 @@ public class PdePreprocessor {
|
||||
PrintWriter outPrintWriter = new PrintWriter(outWriter);
|
||||
outPrintWriter.print(outputProgram);
|
||||
|
||||
hasMain = listener.foundMain();
|
||||
foundMain = listener.foundMain();
|
||||
|
||||
return listener.getResult();
|
||||
}
|
||||
@@ -199,20 +240,249 @@ public class PdePreprocessor {
|
||||
* @return True if a main method was found. False otherwise.
|
||||
*/
|
||||
public boolean hasMain() {
|
||||
return hasMain;
|
||||
return foundMain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory function to create a {PdeParseTreeListener} for use in preprocessing
|
||||
* Get the more or processing-required imports that this preprocessor is using.
|
||||
*
|
||||
* @param tokens The token stream for which the listener needs to be created.
|
||||
* @param sketchName The name of the sketch being preprocessed.
|
||||
* @return Newly created listener suitable for use in this {PdePreprocessor}.
|
||||
* @return List of imports required by processing or this mode.
|
||||
*/
|
||||
private PdeParseTreeListener createListener(CommonTokenStream tokens, String sketchName) {
|
||||
return new PdeParseTreeListener(tokens, sketchName, tabSize);
|
||||
public List<String> getCoreImports() {
|
||||
return coreImports;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get convenience imports provided on the user's behalf.
|
||||
*
|
||||
* @return Imports included by default but not required by processing or the mode.
|
||||
*/
|
||||
public List<String> getDefaultImports() {
|
||||
return defaultImports;
|
||||
}
|
||||
|
||||
/* ========================
|
||||
* === Type Definitions ===
|
||||
* ========================
|
||||
*
|
||||
* The preprocessor has a sizable number of parameters, including those that can modify its
|
||||
* internal behavior. These supporting types help initialize this object and provide hooks for
|
||||
* behavior modifications.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Builder to help instantiate a PdePreprocessor.
|
||||
*
|
||||
* The PdePreprocessor includes a number of parameters, including some behavioral parameters that
|
||||
* change how the parse tree is processed. This builder helps instantiate this object by providing
|
||||
* reasonable defaults for most values but allowing client to (especially modes) to override those
|
||||
* defaults.
|
||||
*/
|
||||
public static class PdePreprocessorBuilder {
|
||||
|
||||
private final String sketchName;
|
||||
private Optional<Integer> tabSize;
|
||||
private Optional<Boolean> isTesting;
|
||||
private Optional<ParseTreeListenerFactory> parseTreeFactory;
|
||||
private Optional<List<String>> defaultImports;
|
||||
private Optional<List<String>> coreImports;
|
||||
private Optional<String> destinationPackage;
|
||||
|
||||
/**
|
||||
* The imports required for the Java processing mode.
|
||||
*
|
||||
* <p>
|
||||
* The set of imports required by processing itself (in java mode) that are made public so that
|
||||
* client code (like in modes) can modify and re-use this list.
|
||||
* </p>
|
||||
*/
|
||||
public static final String[] BASE_CORE_IMPORTS = {
|
||||
"processing.core.*",
|
||||
"processing.data.*",
|
||||
"processing.event.*",
|
||||
"processing.opengl.*"
|
||||
};
|
||||
|
||||
/**
|
||||
* The imports provided as a convenience for the user.
|
||||
*
|
||||
* <p>
|
||||
* The imports that are not strictly required by processing sketches but that are included on
|
||||
* behalf of the user that are made public so that client code (like in modes) can modify and
|
||||
* re-use this list.
|
||||
* </p>
|
||||
*/
|
||||
public static final String[] BASE_DEFAULT_IMPORTS = {
|
||||
"java.util.HashMap",
|
||||
"java.util.ArrayList",
|
||||
"java.io.File",
|
||||
"java.io.BufferedReader",
|
||||
"java.io.PrintWriter",
|
||||
"java.io.InputStream",
|
||||
"java.io.OutputStream",
|
||||
"java.io.IOException"
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a new preprocessor builder.
|
||||
*
|
||||
* <p>
|
||||
* Create a new preprocessor builder which will use default values unless overridden prior to
|
||||
* calling build. Note that client code should use {PdePreprocessor.builderFor} instead of
|
||||
* this constructor.
|
||||
* </p>
|
||||
*
|
||||
* @param newSketchName The name of the sketch.
|
||||
*/
|
||||
private PdePreprocessorBuilder(String newSketchName) {
|
||||
sketchName = newSketchName;
|
||||
tabSize = Optional.empty();
|
||||
isTesting = Optional.empty();
|
||||
parseTreeFactory = Optional.empty();
|
||||
defaultImports = Optional.empty();
|
||||
coreImports = Optional.empty();
|
||||
destinationPackage = Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set how large the tabs should be.
|
||||
*
|
||||
* @param newTabSize The number of spaces in a tab.
|
||||
* @return This builder for method chaining.
|
||||
*/
|
||||
public PdePreprocessorBuilder setTabSize(int newTabSize) {
|
||||
tabSize = Optional.of(newTabSize);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate if this preprocessor is running within unittests.
|
||||
*
|
||||
* @param newIsTesting Flag that, if true, will configure the preprocessor to run safely within
|
||||
* a unit testing environment.
|
||||
* @return This builder for method chaining.
|
||||
*/
|
||||
public PdePreprocessorBuilder setIsTesting(boolean newIsTesting) {
|
||||
isTesting = Optional.of(newIsTesting);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify how the parse tree listener should be built.
|
||||
*
|
||||
* The ANTLR parse tree listener is where the preprocessing edits are generated and some client
|
||||
* code (like modes) may need to override some of the preprocessing edit behavior. Specifying
|
||||
* this factory allows client code to replace the default PdeParseTreeListener that is used
|
||||
* during preprocessing.
|
||||
*
|
||||
* @param newFactory The factory to use in building a parse tree listener.
|
||||
* @return This builder for method chaining.
|
||||
*/
|
||||
public PdePreprocessorBuilder setParseTreeListenerFactory(ParseTreeListenerFactory newFactory) {
|
||||
parseTreeFactory = Optional.of(newFactory);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate which imports are provided on behalf of the user for convenience.
|
||||
*
|
||||
* @param newDefaultImports The new set of default imports.
|
||||
* @return This builder for method chaining.
|
||||
*/
|
||||
public PdePreprocessorBuilder setDefaultImports(List<String> newDefaultImports) {
|
||||
defaultImports = Optional.of(newDefaultImports);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate which imports are required by processing or the mode itself.
|
||||
*
|
||||
* @param newCoreImports The new set of core imports.
|
||||
* @return This builder for method chaining.
|
||||
*/
|
||||
public PdePreprocessorBuilder setCoreImports(List<String> newCoreImports) {
|
||||
coreImports = Optional.of(newCoreImports);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify to which package generated code should be assigned.
|
||||
*
|
||||
* @param newDestinationPackage The package to which output code should be assigned.
|
||||
* @return This builder for method chaining.
|
||||
*/
|
||||
public PdePreprocessorBuilder setDestinationPackage(String newDestinationPackage) {
|
||||
destinationPackage = Optional.of(newDestinationPackage);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the preprocessor.
|
||||
*
|
||||
* @return Newly built preproceesor.
|
||||
*/
|
||||
public PdePreprocessor build() {
|
||||
final int effectiveTabSize = tabSize.orElseGet(
|
||||
() -> Preferences.getInteger("editor.tabs.size")
|
||||
);
|
||||
|
||||
final boolean effectiveIsTesting = isTesting.orElse(false);
|
||||
|
||||
ParseTreeListenerFactory effectiveFactory = parseTreeFactory.orElse(
|
||||
PdeParseTreeListener::new
|
||||
);
|
||||
|
||||
List<String> effectiveDefaultImports = defaultImports.orElseGet(
|
||||
() -> Arrays.asList(BASE_DEFAULT_IMPORTS)
|
||||
);
|
||||
|
||||
List<String> effectiveCoreImports = coreImports.orElseGet(
|
||||
() -> Arrays.asList(BASE_CORE_IMPORTS)
|
||||
);
|
||||
|
||||
return new PdePreprocessor(
|
||||
sketchName,
|
||||
effectiveTabSize,
|
||||
effectiveIsTesting,
|
||||
effectiveFactory,
|
||||
effectiveDefaultImports,
|
||||
effectiveCoreImports,
|
||||
destinationPackage
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory which creates parse tree traversal listeners.
|
||||
*
|
||||
* The ANTLR parse tree listener is where the preprocessing edits are generated and some client
|
||||
* code (like modes) may need to override some of the preprocessing edit behavior. Specifying
|
||||
* this factory allows client code to replace the default PdeParseTreeListener that is used
|
||||
* during preprocessing.
|
||||
*/
|
||||
public static interface ParseTreeListenerFactory {
|
||||
|
||||
/**
|
||||
* Create a new processing listener.
|
||||
*
|
||||
* @param tokens The token stream with sketch code contents.
|
||||
* @param sketchName The name of the sketch that will be preprocessed.
|
||||
* @param tabSize The size (number of spaces) of the tabs.
|
||||
* @param packageName The optional package name for generated code.
|
||||
* @return The newly created listener.
|
||||
*/
|
||||
PdeParseTreeListener build(CommonTokenStream tokens, String sketchName, int tabSize,
|
||||
Optional<String> packageName);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* ==================================
|
||||
* === Internal Utility Functions ===
|
||||
* ==================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* Utility function to substitute non ascii characters for escaped unicode character sequences.
|
||||
*
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2012-19 The Processing Foundation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.mode.java.preproc;
|
||||
|
||||
|
||||
/**
|
||||
* Simple interface for strategy which can emit the full body of a processing sketch.
|
||||
*/
|
||||
public interface SourceEmitter {
|
||||
|
||||
/**
|
||||
* Get the full body of the processing sketch.
|
||||
*
|
||||
* @return String processing sketch source code across all tabs.
|
||||
*/
|
||||
String getSource();
|
||||
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
package processing.mode.java.preproc.code;
|
||||
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.antlr.v4.runtime.TokenStreamRewriter;
|
||||
import processing.mode.java.pdex.TextTransform;
|
||||
|
||||
|
||||
/**
|
||||
* Utility which generates and performs code edit operations.
|
||||
*
|
||||
* <p>
|
||||
* Utility which generates and performs code edit operations, performing the edit immediately
|
||||
* within a ANTLR rewriter but also generating a {TextTransform.Edit} for use with the JDT.
|
||||
* </p>
|
||||
*/
|
||||
public class CodeEditOperationUtil {
|
||||
|
||||
/**
|
||||
* Delete a single token.
|
||||
*
|
||||
* @param start The token to be deleted.
|
||||
* @param rewriter The rewriter in which to immediately edit.
|
||||
* @return The {TextTransform.Edit} corresponding to this change.
|
||||
*/
|
||||
public static TextTransform.Edit createDelete(Token start, TokenStreamRewriter rewriter) {
|
||||
rewriter.delete(start);
|
||||
return TextTransform.Edit.delete(start.getStartIndex(), start.getText().length());
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete tokens between a start end end token inclusive.
|
||||
*
|
||||
* @param start The token to be deleted.
|
||||
* @param stop The final token to be deleted.
|
||||
* @param rewriter The rewriter in which to immediately edit.
|
||||
* @return The {TextTransform.Edit} corresponding to this change.
|
||||
*/
|
||||
public static TextTransform.Edit createDelete(Token start, Token stop,
|
||||
TokenStreamRewriter rewriter) {
|
||||
|
||||
rewriter.delete(start, stop);
|
||||
|
||||
int startIndex = start.getStartIndex();
|
||||
int length = stop.getStopIndex() - startIndex + 1;
|
||||
|
||||
return TextTransform.Edit.delete(
|
||||
startIndex,
|
||||
length
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert text after a token.
|
||||
*
|
||||
* @param start The position after which the text should be inserted.
|
||||
* @param text The text to insert.
|
||||
* @param rewriter The rewriter in which to immediately edit.
|
||||
* @return The {TextTransform.Edit} corresponding to this change.
|
||||
*/
|
||||
public static TextTransform.Edit createInsertAfter(int start, String text,
|
||||
TokenStreamRewriter rewriter) {
|
||||
|
||||
rewriter.insertAfter(start, text);
|
||||
|
||||
return TextTransform.Edit.insert(
|
||||
start + 1,
|
||||
text
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert text after a token.
|
||||
*
|
||||
* @param start The token after which the text should be inserted.
|
||||
* @param text The text to insert.
|
||||
* @param rewriter The rewriter in which to immediately edit.
|
||||
* @return The {TextTransform.Edit} corresponding to this change.
|
||||
*/
|
||||
public static TextTransform.Edit createInsertAfter(Token start, String text,
|
||||
TokenStreamRewriter rewriter) {
|
||||
|
||||
rewriter.insertAfter(start, text);
|
||||
|
||||
return TextTransform.Edit.insert(
|
||||
start.getStopIndex() + 1,
|
||||
text
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert text before a token.
|
||||
*
|
||||
* @param before Token before which the text should be inserted.
|
||||
* @param text The text to insert.
|
||||
* @param rewriter The rewriter in which to immediately edit.
|
||||
* @return The {TextTransform.Edit} corresponding to this change.
|
||||
*/
|
||||
public static TextTransform.Edit createInsertBefore(Token before, String text,
|
||||
TokenStreamRewriter rewriter) {
|
||||
|
||||
rewriter.insertBefore(before, text);
|
||||
|
||||
return TextTransform.Edit.insert(
|
||||
before.getStartIndex(),
|
||||
text
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert text before a position in code.
|
||||
*
|
||||
* @param before The location before which to insert the text in tokens.
|
||||
* @param beforeOffset THe location before which to insert the text in chars.
|
||||
* @param text The text to insert.
|
||||
* @param rewriter The rewriter in which to immediately edit.
|
||||
* @return The {TextTransform.Edit} corresponding to this change.
|
||||
*/
|
||||
public static TextTransform.Edit createInsertBefore(int before, int beforeOffset, String text,
|
||||
TokenStreamRewriter rewriter) {
|
||||
|
||||
rewriter.insertBefore(before, text);
|
||||
|
||||
return TextTransform.Edit.insert(
|
||||
beforeOffset,
|
||||
text
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package processing.mode.java.preproc.code;
|
||||
|
||||
|
||||
/**
|
||||
* Utility to assist with preprocessing imports.
|
||||
*/
|
||||
public class ImportUtil {
|
||||
|
||||
/**
|
||||
* Get the imports required by processing itself.
|
||||
*
|
||||
* @return List of imports required by processing itself.
|
||||
*/
|
||||
public static String[] getCoreImports() {
|
||||
return new String[] {
|
||||
"processing.core.*",
|
||||
"processing.data.*",
|
||||
"processing.event.*",
|
||||
"processing.opengl.*"
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of imports included by default on behalf of the user.
|
||||
*
|
||||
* @return List of "default" imports not required for processing but included for user
|
||||
* convenience.
|
||||
*/
|
||||
public static String[] getDefaultImports() {
|
||||
// These may change in-between (if the prefs panel adds this option)
|
||||
//String prefsLine = Preferences.get("preproc.imports");
|
||||
//return PApplet.splitTokens(prefsLine, ", ");
|
||||
return new String[] {
|
||||
"java.util.HashMap",
|
||||
"java.util.ArrayList",
|
||||
"java.io.File",
|
||||
"java.io.BufferedReader",
|
||||
"java.io.PrintWriter",
|
||||
"java.io.InputStream",
|
||||
"java.io.OutputStream",
|
||||
"java.io.IOException"
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,91 +1,7 @@
|
||||
package processing.mode.java.preproc.code;
|
||||
|
||||
import org.antlr.v4.runtime.TokenStreamRewriter;
|
||||
import processing.mode.java.preproc.PdeParseTreeListener;
|
||||
|
||||
|
||||
/**
|
||||
* Decorator around a {TokenStreamRewriter}.
|
||||
*
|
||||
* <p>
|
||||
* Decorator around a {TokenStreamRewriter} which converts input commands into something that the
|
||||
* rewriter can understand but also generates edits saved to an input RewriteResultBuilder.
|
||||
* Requires a call to finish() after completion of preprocessing.
|
||||
* </p>
|
||||
*/
|
||||
public class PrintWriterWithEditGen {
|
||||
|
||||
private final TokenStreamRewriter writer;
|
||||
private final RewriteResultBuilder rewriteResultBuilder;
|
||||
private final int insertPoint;
|
||||
private final StringBuilder editBuilder;
|
||||
private final boolean before;
|
||||
|
||||
/**
|
||||
* Create a new edit generator decorator.
|
||||
*
|
||||
* @param writer The writer to which edits should be immediately made.
|
||||
* @param newRewriteResultBuilder The builder to which edits should be saved.
|
||||
* @param newInsertPoint The point at which new values should be inserted.
|
||||
* @param newBefore If true, the values will be inserted before the given insert point. If false,
|
||||
* will, insert after the insertion point.
|
||||
*/
|
||||
public PrintWriterWithEditGen(TokenStreamRewriter writer,
|
||||
RewriteResultBuilder newRewriteResultBuilder, int newInsertPoint, boolean newBefore) {
|
||||
|
||||
this.writer = writer;
|
||||
rewriteResultBuilder = newRewriteResultBuilder;
|
||||
insertPoint = newInsertPoint;
|
||||
editBuilder = new StringBuilder();
|
||||
before = newBefore;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an empty line into the code.
|
||||
*/
|
||||
public void addEmptyLine() {
|
||||
addCode("\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Add code with a newline automatically appended.
|
||||
*
|
||||
* @param newCode The code to add.
|
||||
*/
|
||||
public void addCodeLine(String newCode) {
|
||||
addCode(newCode + "\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Add code without a new line.
|
||||
*
|
||||
* @param newCode The code to add.
|
||||
*/
|
||||
public void addCode(String newCode) {
|
||||
editBuilder.append(newCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalize edits made through this decorator.
|
||||
*/
|
||||
public void finish() {
|
||||
String newCode = editBuilder.toString();
|
||||
|
||||
if (before) {
|
||||
rewriteResultBuilder.addEdit(CodeEditOperationUtil.createInsertBefore(
|
||||
insertPoint,
|
||||
insertPoint,
|
||||
newCode,
|
||||
writer
|
||||
));
|
||||
} else {
|
||||
rewriteResultBuilder.addEdit(CodeEditOperationUtil.createInsertAfter(
|
||||
insertPoint,
|
||||
newCode,
|
||||
writer
|
||||
));
|
||||
}
|
||||
|
||||
rewriteResultBuilder.addOffset(SyntaxUtil.getCount(newCode, "\n"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,229 +0,0 @@
|
||||
package processing.mode.java.preproc.code;
|
||||
|
||||
import org.antlr.v4.runtime.TokenStreamRewriter;
|
||||
import processing.mode.java.pdex.ImportStatement;
|
||||
import processing.mode.java.preproc.PdePreprocessor;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
/**
|
||||
* Set of parameters required for re-writing as part of sketch preprocessing.
|
||||
*/
|
||||
public class RewriteParams {
|
||||
|
||||
private final String version;
|
||||
private final String sketchName;
|
||||
private final boolean isTesting;
|
||||
private final TokenStreamRewriter rewriter;
|
||||
private final PdePreprocessor.Mode mode;
|
||||
private final boolean foundMain;
|
||||
private final int lineOffset;
|
||||
private final List<ImportStatement> coreImports;
|
||||
private final List<ImportStatement> defaultImports;
|
||||
private final List<ImportStatement> codeFolderImports;
|
||||
private final List<ImportStatement> foundImports;
|
||||
private final Optional<String> sketchWidth;
|
||||
private final Optional<String> sketchHeight;
|
||||
private final Optional<String> sketchRenderer;
|
||||
private final boolean isSizeValidInGlobal;
|
||||
private final boolean isSizeFullscreen;
|
||||
|
||||
/**
|
||||
* Create a new set of parameters.
|
||||
*
|
||||
* @param newVersion The version of the preprocessor.
|
||||
* @param newSketchName The name of the sketch.
|
||||
* @param newisTesting Flag indicating if this is being run as part of automated testing.
|
||||
* @param newRewriter The rewriter into which edits should be made.
|
||||
* @param newMode The mode (like STATIC) in which processing is being run.
|
||||
* @param newFoundMain Flag indicating if a user-provided main method was found in preprocessing.
|
||||
* @param newLineOffset The line offset of the preprocessor prior to rewrite.
|
||||
* @param newCoreImports The set of imports to include that are required for processing.
|
||||
* @param newDefaultImports The set of imports included for user convenience.
|
||||
* @param newCodeFolderImports The imports required to include other code in the code folder.
|
||||
* @param newFoundImports The imports included by the user.
|
||||
* @param newSketchWidth The width of the sketch or code used to generate it. If not included,
|
||||
* call to size will not be made.
|
||||
* @param newSketchHeight The height of the sketch or code used to generate it. If not included,
|
||||
* call to size will not be made.
|
||||
* @param newSketchRenderer The renderer like P2D.
|
||||
* @param newIsSizeValidInGlobal Flag indicating if a call to size is valid when that call to size
|
||||
* is made from sketch global context.
|
||||
* @param newSizeIsFullscreen Indicate if in fullscreen mode.
|
||||
*/
|
||||
public RewriteParams(String newVersion, String newSketchName, boolean newisTesting,
|
||||
TokenStreamRewriter newRewriter, PdePreprocessor.Mode newMode,
|
||||
boolean newFoundMain, int newLineOffset, List<ImportStatement> newCoreImports,
|
||||
List<ImportStatement> newDefaultImports, List<ImportStatement> newCodeFolderImports,
|
||||
List<ImportStatement> newFoundImports, Optional<String> newSketchWidth,
|
||||
Optional<String> newSketchHeight, Optional<String> newSketchRenderer,
|
||||
boolean newIsSizeValidInGlobal, boolean newSizeIsFullscreen) {
|
||||
|
||||
version = newVersion;
|
||||
sketchName = newSketchName;
|
||||
isTesting = newisTesting;
|
||||
rewriter = newRewriter;
|
||||
mode = newMode;
|
||||
foundMain = newFoundMain;
|
||||
lineOffset = newLineOffset;
|
||||
coreImports = newCoreImports;
|
||||
defaultImports = newDefaultImports;
|
||||
codeFolderImports = newCodeFolderImports;
|
||||
foundImports = newFoundImports;
|
||||
sketchWidth = newSketchWidth;
|
||||
sketchHeight = newSketchHeight;
|
||||
sketchRenderer = newSketchRenderer;
|
||||
isSizeValidInGlobal = newIsSizeValidInGlobal;
|
||||
isSizeFullscreen = newSizeIsFullscreen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the version of the preprocessor.
|
||||
*
|
||||
* @return The version of the preprocessor.
|
||||
*/
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* The user provided or automated name of the sketch.
|
||||
*
|
||||
* @return The name of the sketch.
|
||||
*/
|
||||
public String getSketchName() {
|
||||
return sketchName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if this code is being exercised in automated test.
|
||||
*
|
||||
* @return Flag indicating if this is being run as part of automated testing.
|
||||
*/
|
||||
public boolean getisTesting() {
|
||||
return isTesting;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rewriter to be used in rewriting.
|
||||
*
|
||||
* @return The rewriter into which edits should be made.
|
||||
*/
|
||||
public TokenStreamRewriter getRewriter() {
|
||||
return rewriter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mode in which processing is being run.
|
||||
*
|
||||
* @return The mode (like STATIC) in which processing is being run.
|
||||
*/
|
||||
public PdePreprocessor.Mode getMode() {
|
||||
return mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the user provided their own main method.
|
||||
*
|
||||
* @return Flag indicating if a user-provided main method was found in preprocessing.
|
||||
*/
|
||||
public boolean getFoundMain() {
|
||||
return foundMain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the line offset of the preprocessor prior to rewrite.
|
||||
*
|
||||
* @return The line offset of the preprocessor prior to rewrite.
|
||||
*/
|
||||
public int getLineOffset() {
|
||||
return lineOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get imports required for processing.
|
||||
*
|
||||
* @return The set of imports to include that are required for processing.
|
||||
*/
|
||||
public List<ImportStatement> getCoreImports() {
|
||||
return coreImports;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the imports added for user convenience.
|
||||
*
|
||||
* @return The set of imports included for user convenience.
|
||||
*/
|
||||
public List<ImportStatement> getDefaultImports() {
|
||||
return defaultImports;
|
||||
}
|
||||
|
||||
/**
|
||||
* The imports required to access other code in the code folder.
|
||||
*
|
||||
* @return The imports required to include other code in the code folder.
|
||||
*/
|
||||
public List<ImportStatement> getCodeFolderImports() {
|
||||
return codeFolderImports;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the users included by the user.
|
||||
*
|
||||
* @return The imports included by the user.
|
||||
*/
|
||||
public List<ImportStatement> getFoundImports() {
|
||||
return foundImports;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the code used to determine sketch width if given.
|
||||
*
|
||||
* @return The width of the sketch or code used to generate it. If not included, call to size will
|
||||
* not be made. Not included means it is an empty optional.
|
||||
*/
|
||||
public Optional<String> getSketchWidth() {
|
||||
return sketchWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the code used to determine sketch height if given.
|
||||
*
|
||||
* @return The height of the sketch or code used to generate it. If not included, call to size
|
||||
* will not be made. Not included means it is an empty optional.
|
||||
*/
|
||||
public Optional<String> getSketchHeight() {
|
||||
return sketchHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user provided renderer or an empty optional if user has not provided renderer.
|
||||
*
|
||||
* @return The renderer like P2D if given.
|
||||
*/
|
||||
public Optional<String> getSketchRenderer() {
|
||||
return sketchRenderer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a call to size has been made in sketch global context.
|
||||
*
|
||||
* @return Flag indicating if a call to size is valid when that call to size is made from sketch
|
||||
* global context.
|
||||
*/
|
||||
public boolean getIsSizeValidInGlobal() {
|
||||
return isSizeValidInGlobal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if running in fullscreen.
|
||||
*
|
||||
* @return Flag indicating if in running in fullscreen.
|
||||
*/
|
||||
public boolean getIsSizeFullscreen() {
|
||||
return isSizeFullscreen;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,257 +0,0 @@
|
||||
package processing.mode.java.preproc.code;
|
||||
|
||||
import org.antlr.v4.runtime.TokenStreamRewriter;
|
||||
import processing.mode.java.pdex.ImportStatement;
|
||||
import processing.mode.java.preproc.PdePreprocessor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
/**
|
||||
* Builder to help generate a {RewriteParams}.
|
||||
*/
|
||||
public class RewriteParamsBuilder {
|
||||
|
||||
private final String version;
|
||||
|
||||
private Optional<String> sketchName;
|
||||
private Optional<Boolean> isTesting;
|
||||
private Optional<TokenStreamRewriter> rewriter;
|
||||
private Optional<PdePreprocessor.Mode> mode;
|
||||
private Optional<Boolean> foundMain;
|
||||
private Optional<Integer> lineOffset;
|
||||
private Optional<String> sketchWidth;
|
||||
private Optional<String> sketchHeight;
|
||||
private Optional<String> sketchRenderer;
|
||||
private Optional<Boolean> isSizeValidInGlobal;
|
||||
private Optional<Boolean> isSizeFullscreen;
|
||||
|
||||
private ArrayList<ImportStatement> coreImports;
|
||||
private ArrayList<ImportStatement> defaultImports;
|
||||
private ArrayList<ImportStatement> codeFolderImports;
|
||||
private ArrayList<ImportStatement> foundImports;
|
||||
|
||||
/**
|
||||
* Create a new params build.
|
||||
*
|
||||
* @param newVersion The version to include in generated RewriteParams.
|
||||
*/
|
||||
public RewriteParamsBuilder(String newVersion) {
|
||||
version = newVersion;
|
||||
|
||||
coreImports = new ArrayList<>();
|
||||
defaultImports = new ArrayList<>();
|
||||
codeFolderImports = new ArrayList<>();
|
||||
foundImports = new ArrayList<>();
|
||||
|
||||
sketchName = Optional.empty();
|
||||
isTesting = Optional.empty();
|
||||
rewriter = Optional.empty();
|
||||
mode = Optional.empty();
|
||||
foundMain = Optional.empty();
|
||||
lineOffset = Optional.empty();
|
||||
sketchWidth = Optional.empty();
|
||||
sketchHeight = Optional.empty();
|
||||
sketchRenderer = Optional.empty();
|
||||
isSizeValidInGlobal = Optional.empty();
|
||||
isSizeFullscreen = Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the name of the sketch.
|
||||
*
|
||||
* @param newSketchName The name of the sketch.
|
||||
*/
|
||||
public void setSketchName(String newSketchName) {
|
||||
sketchName = Optional.ofNullable(newSketchName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify if this is being run as part of automated testing.
|
||||
*
|
||||
* @param newisTesting Flag indicating if this is being run as part of automated testing.
|
||||
*/
|
||||
public void setisTesting(boolean newisTesting) {
|
||||
isTesting = Optional.of(newisTesting);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify rewriter into which edits should be made.
|
||||
*
|
||||
* @param newRewriter The rewriter into which edits should be made.
|
||||
*/
|
||||
public void setRewriter(TokenStreamRewriter newRewriter) {
|
||||
rewriter = Optional.ofNullable(newRewriter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify mode (like STATIC) in which processing is being run.
|
||||
*
|
||||
* @param newMode The mode (like STATIC) in which processing is being run.
|
||||
*/
|
||||
public void setMode(PdePreprocessor.Mode newMode) {
|
||||
mode = Optional.ofNullable(newMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify if a user-provided main method was found in preprocessing.
|
||||
*
|
||||
* @param newFoundMain Flag indicating if a user-provided main method was found in preprocessing.
|
||||
*/
|
||||
public void setFoundMain(boolean newFoundMain) {
|
||||
foundMain = Optional.of(newFoundMain);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify line offset of the preprocessor prior to rewrite.
|
||||
*
|
||||
* @param newLineOffset The line offset of the preprocessor prior to rewrite.
|
||||
*/
|
||||
public void setLineOffset(int newLineOffset) {
|
||||
lineOffset = Optional.of(newLineOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify width of the sketch.
|
||||
*
|
||||
* @param newSketchWidth The width of the sketch or code used to generate it. If not included,
|
||||
* call to size will not be made.
|
||||
*/
|
||||
public void setSketchWidth(String newSketchWidth) {
|
||||
sketchWidth = Optional.ofNullable(newSketchWidth);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify height of the sketch.
|
||||
*
|
||||
* @param newSketchHeight The height of the sketch or code used to generate it. If not included,
|
||||
* call to size will not be made.
|
||||
*/
|
||||
public void setSketchHeight(String newSketchHeight) {
|
||||
sketchHeight = Optional.ofNullable(newSketchHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify renderer like P2D.
|
||||
*
|
||||
* @param newSketchRenderer The renderer like P2D.
|
||||
*/
|
||||
public void setSketchRenderer(String newSketchRenderer) {
|
||||
sketchRenderer = Optional.ofNullable(newSketchRenderer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify if the user made a valid call to size in sketch global context.
|
||||
*
|
||||
* @param newIsSizeValidInGlobal Flag indicating if a call to size is valid when that call to size
|
||||
* is made from sketch global context.
|
||||
*/
|
||||
public void setIsSizeValidInGlobal(boolean newIsSizeValidInGlobal) {
|
||||
isSizeValidInGlobal = Optional.of(newIsSizeValidInGlobal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify if running in fullscreen.
|
||||
*
|
||||
* @param newIsSizeFullscreen Flag indicating if running in fullscreen.
|
||||
*/
|
||||
public void setIsSizeFullscreen(boolean newIsSizeFullscreen) {
|
||||
isSizeFullscreen = Optional.of(newIsSizeFullscreen);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add imports required for processing to function.
|
||||
*
|
||||
* @param newImports The set of imports to include that are required for processing.
|
||||
*/
|
||||
public void addCoreImports(Collection<ImportStatement> newImports) {
|
||||
coreImports.addAll(newImports);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add imports that are included ahead of time for the user.
|
||||
*
|
||||
* @param newImports The set of imports included for user convenience.
|
||||
*/
|
||||
public void addDefaultImports(Collection<ImportStatement> newImports) {
|
||||
defaultImports.addAll(newImports);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add imports required for the sketch to reach code in its own code folder.
|
||||
*
|
||||
* @param newImports The imports required to include other code in the code folder.
|
||||
*/
|
||||
public void addCodeFolderImports(Collection<ImportStatement> newImports) {
|
||||
codeFolderImports.addAll(newImports);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add imports included manually by the user.
|
||||
*
|
||||
* @param newImports The imports included by the user.
|
||||
*/
|
||||
public void addFoundImports(Collection<ImportStatement> newImports) {
|
||||
foundImports.addAll(newImports);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a new set of rewrite parameters.
|
||||
*
|
||||
* @return Parameters required to execute {RewriterCodeGenerator};
|
||||
*/
|
||||
public RewriteParams build() {
|
||||
if (sketchName.isEmpty()) {
|
||||
throw new RuntimeException("Expected sketchName to be set");
|
||||
}
|
||||
|
||||
if (isTesting.isEmpty()) {
|
||||
throw new RuntimeException("Expected isTesting to be set");
|
||||
}
|
||||
|
||||
if (rewriter.isEmpty()) {
|
||||
throw new RuntimeException("Expected rewriter to be set");
|
||||
}
|
||||
|
||||
if (mode.isEmpty()) {
|
||||
throw new RuntimeException("Expected mode to be set");
|
||||
}
|
||||
|
||||
if (foundMain.isEmpty()) {
|
||||
throw new RuntimeException("Expected foundMain to be set");
|
||||
}
|
||||
|
||||
if (lineOffset.isEmpty()) {
|
||||
throw new RuntimeException("Expected lineOffset to be set");
|
||||
}
|
||||
|
||||
if (isSizeValidInGlobal.isEmpty()) {
|
||||
throw new RuntimeException("Expected isSizeValidInGlobal to be set");
|
||||
}
|
||||
|
||||
if (isSizeFullscreen.isEmpty()) {
|
||||
throw new RuntimeException("Expected isSizeFullscreen to be set");
|
||||
}
|
||||
|
||||
return new RewriteParams(
|
||||
version,
|
||||
sketchName.get(),
|
||||
isTesting.get(),
|
||||
rewriter.get(),
|
||||
mode.get(),
|
||||
foundMain.get(),
|
||||
lineOffset.get(),
|
||||
coreImports,
|
||||
defaultImports,
|
||||
codeFolderImports,
|
||||
foundImports,
|
||||
sketchWidth,
|
||||
sketchHeight,
|
||||
sketchRenderer,
|
||||
isSizeValidInGlobal.get(),
|
||||
isSizeFullscreen.get()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,333 +0,0 @@
|
||||
package processing.mode.java.preproc.code;
|
||||
|
||||
import org.antlr.v4.runtime.TokenStreamRewriter;
|
||||
import processing.app.Preferences;
|
||||
import processing.core.PApplet;
|
||||
import processing.mode.java.pdex.ImportStatement;
|
||||
import processing.mode.java.preproc.PdePreprocessor;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
|
||||
/**
|
||||
* Utility to rewrite code as part of preprocessing.
|
||||
*/
|
||||
public class RewriterCodeGenerator {
|
||||
|
||||
private final String indent1;
|
||||
private final String indent2;
|
||||
private final String indent3;
|
||||
|
||||
/**
|
||||
* Create a new rewriter.
|
||||
*
|
||||
* @param indentSize Number of spaces in the indent.
|
||||
*/
|
||||
public RewriterCodeGenerator(int indentSize) {
|
||||
final char[] indentChars = new char[indentSize];
|
||||
Arrays.fill(indentChars, ' ');
|
||||
indent1 = new String(indentChars);
|
||||
indent2 = indent1 + indent1;
|
||||
indent3 = indent2 + indent1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write preface code to wrap sketch code so that it is contained within a proper Java definition.
|
||||
*
|
||||
* @param headerWriter The writer into which the header should be written.
|
||||
* @param params The parameters for the rewrite.
|
||||
* @return Information about the completed rewrite.
|
||||
*/
|
||||
public RewriteResult writeHeader(TokenStreamRewriter headerWriter, RewriteParams params) {
|
||||
|
||||
RewriteResultBuilder resultBuilder = new RewriteResultBuilder();
|
||||
|
||||
PrintWriterWithEditGen decoratedWriter = new PrintWriterWithEditGen(
|
||||
headerWriter,
|
||||
resultBuilder,
|
||||
0,
|
||||
true
|
||||
);
|
||||
|
||||
if (!params.getisTesting()) writePreprocessorComment(decoratedWriter, params, resultBuilder);
|
||||
writeImports(decoratedWriter, params, resultBuilder);
|
||||
|
||||
PdePreprocessor.Mode mode = params.getMode();
|
||||
|
||||
boolean requiresClassHeader = mode == PdePreprocessor.Mode.STATIC;
|
||||
requiresClassHeader = requiresClassHeader || mode == PdePreprocessor.Mode.ACTIVE;
|
||||
|
||||
boolean requiresStaticSketchHeader = mode == PdePreprocessor.Mode.STATIC;
|
||||
|
||||
if (requiresClassHeader) {
|
||||
writeClassHeader(decoratedWriter, params, resultBuilder);
|
||||
}
|
||||
|
||||
if (requiresStaticSketchHeader) {
|
||||
writeStaticSketchHeader(decoratedWriter, params, resultBuilder);
|
||||
}
|
||||
|
||||
decoratedWriter.finish();
|
||||
|
||||
return resultBuilder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the footer for a sketch (finishes the constructs introduced in header like class def).
|
||||
*
|
||||
* @param footerWriter The writer through which the footer should be introduced.
|
||||
* @param params The parameters for the rewrite.
|
||||
* @param insertPoint The loction at which the footer should be written.
|
||||
* @return Information about the completed rewrite.
|
||||
*/
|
||||
public RewriteResult writeFooter(TokenStreamRewriter footerWriter, RewriteParams params,
|
||||
int insertPoint) {
|
||||
|
||||
RewriteResultBuilder resultBuilder = new RewriteResultBuilder();
|
||||
|
||||
PrintWriterWithEditGen decoratedWriter = new PrintWriterWithEditGen(
|
||||
footerWriter,
|
||||
resultBuilder,
|
||||
insertPoint,
|
||||
false
|
||||
);
|
||||
|
||||
decoratedWriter.addEmptyLine();
|
||||
|
||||
PdePreprocessor.Mode mode = params.getMode();
|
||||
|
||||
boolean requiresStaticSketchFooter = mode == PdePreprocessor.Mode.STATIC;
|
||||
boolean requiresClassWrap = mode == PdePreprocessor.Mode.STATIC;
|
||||
requiresClassWrap = requiresClassWrap || mode == PdePreprocessor.Mode.ACTIVE;
|
||||
|
||||
if (requiresStaticSketchFooter) {
|
||||
writeStaticSketchFooter(decoratedWriter, params, resultBuilder);
|
||||
}
|
||||
|
||||
if (requiresClassWrap) {
|
||||
writeExtraFieldsAndMethods(decoratedWriter, params, resultBuilder);
|
||||
if (!params.getFoundMain()) writeMain(decoratedWriter, params, resultBuilder);
|
||||
writeClassFooter(decoratedWriter, params, resultBuilder);
|
||||
}
|
||||
|
||||
decoratedWriter.finish();
|
||||
|
||||
return resultBuilder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Comment out sketch code before it is moved elsewhere in resulting Java.
|
||||
*
|
||||
* @param headerWriter The writer though which the comment should be introduced.
|
||||
* @param params The parameters for the rewrite.
|
||||
* @param resultBuilder Builder for reporting out results to the caller.
|
||||
*/
|
||||
private void writePreprocessorComment(PrintWriterWithEditGen headerWriter, RewriteParams params,
|
||||
RewriteResultBuilder resultBuilder) {
|
||||
|
||||
String dateStr = new SimpleDateFormat("YYYY-MM-dd").format(new Date());
|
||||
|
||||
String newCode = String.format(
|
||||
"/* autogenerated by Processing preprocessor v%s on %s */",
|
||||
params.getVersion(),
|
||||
dateStr
|
||||
);
|
||||
|
||||
headerWriter.addCodeLine(newCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add imports as part of conversion from processing sketch to Java code.
|
||||
*
|
||||
* @param headerWriter The writer though which the imports should be introduced.
|
||||
* @param params The parameters for the rewrite.
|
||||
* @param resultBuilder Builder for reporting out results to the caller.
|
||||
*/
|
||||
private void writeImports(PrintWriterWithEditGen headerWriter, RewriteParams params,
|
||||
RewriteResultBuilder resultBuilder) {
|
||||
|
||||
writeImportList(headerWriter, params.getCoreImports(), params, resultBuilder);
|
||||
writeImportList(headerWriter, params.getCodeFolderImports(), params, resultBuilder);
|
||||
writeImportList(headerWriter, params.getFoundImports(), params, resultBuilder);
|
||||
writeImportList(headerWriter, params.getDefaultImports(), params, resultBuilder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a list of imports.
|
||||
*
|
||||
* @param headerWriter The writer though which the imports should be introduced.
|
||||
* @param imports Collection of imports to introduce.
|
||||
* @param params The parameters for the rewrite.
|
||||
* @param resultBuilder Builder for reporting out results to the caller.
|
||||
*/
|
||||
private void writeImportList(PrintWriterWithEditGen headerWriter, List<ImportStatement> imports, RewriteParams params,
|
||||
RewriteResultBuilder resultBuilder) {
|
||||
|
||||
writeImportList(headerWriter, imports.toArray(new ImportStatement[0]), params, resultBuilder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a list of imports.
|
||||
*
|
||||
* @param headerWriter The writer though which the imports should be introduced.
|
||||
* @param imports Collection of imports to introduce.
|
||||
* @param params The parameters for the rewrite.
|
||||
* @param resultBuilder Builder for reporting out results to the caller.
|
||||
*/
|
||||
private void writeImportList(PrintWriterWithEditGen headerWriter, ImportStatement[] imports, RewriteParams params,
|
||||
RewriteResultBuilder resultBuilder) {
|
||||
|
||||
for (ImportStatement importDecl : imports) {
|
||||
headerWriter.addCodeLine(importDecl.getFullSourceLine());
|
||||
}
|
||||
if (imports.length > 0) {
|
||||
headerWriter.addEmptyLine();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the prefix which defines the enclosing class for the sketch.
|
||||
*
|
||||
* @param headerWriter The writer through which the header should be introduced.
|
||||
* @param params The parameters for the rewrite.
|
||||
* @param resultBuilder Builder for reporting out results to the caller.
|
||||
*/
|
||||
private void writeClassHeader(PrintWriterWithEditGen headerWriter, RewriteParams params,
|
||||
RewriteResultBuilder resultBuilder) {
|
||||
|
||||
headerWriter.addCodeLine("public class " + params.getSketchName() + " extends PApplet {");
|
||||
|
||||
headerWriter.addEmptyLine();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the header for a static sketch (no methods).
|
||||
*
|
||||
* @param headerWriter The writer through which the header should be introduced.
|
||||
* @param params The parameters for the rewrite.
|
||||
* @param resultBuilder Builder for reporting out results to the caller.
|
||||
*/
|
||||
private void writeStaticSketchHeader(PrintWriterWithEditGen headerWriter, RewriteParams params,
|
||||
RewriteResultBuilder resultBuilder) {
|
||||
|
||||
headerWriter.addCodeLine(indent1 + "public void setup() {");
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the bottom of the sketch code for static mode.
|
||||
*
|
||||
* @param footerWriter The footer into which the text should be written.
|
||||
* @param params The parameters for the rewrite.
|
||||
* @param resultBuilder Builder for reporting out results to the caller.
|
||||
*/
|
||||
private void writeStaticSketchFooter(PrintWriterWithEditGen footerWriter, RewriteParams params,
|
||||
RewriteResultBuilder resultBuilder) {
|
||||
|
||||
footerWriter.addCodeLine(indent2 + "noLoop();");
|
||||
footerWriter.addCodeLine(indent1 + "}");
|
||||
}
|
||||
|
||||
/**
|
||||
* Write code supporting speical functions like size.
|
||||
*
|
||||
* @param classBodyWriter The writer into which the code should be written. Should be for class
|
||||
* body.
|
||||
* @param params The parameters for the rewrite.
|
||||
* @param resultBuilder Builder for reporting out results to the caller.
|
||||
*/
|
||||
private void writeExtraFieldsAndMethods(PrintWriterWithEditGen classBodyWriter, RewriteParams params,
|
||||
RewriteResultBuilder resultBuilder) {
|
||||
|
||||
if (!params.getIsSizeValidInGlobal()) {
|
||||
return;
|
||||
}
|
||||
|
||||
String settingsOuterTemplate = indent1 + "public void settings() { %s }";
|
||||
|
||||
String settingsInner;
|
||||
if (params.getIsSizeFullscreen()) {
|
||||
String fullscreenInner = params.getSketchRenderer().orElse("");
|
||||
settingsInner = String.format("fullScreen(%s);", fullscreenInner);
|
||||
} else {
|
||||
|
||||
if (params.getSketchWidth().isEmpty() || params.getSketchHeight().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
StringJoiner argJoiner = new StringJoiner(",");
|
||||
argJoiner.add(params.getSketchWidth().get());
|
||||
argJoiner.add(params.getSketchHeight().get());
|
||||
|
||||
if (params.getSketchRenderer().isPresent()) {
|
||||
argJoiner.add(params.getSketchRenderer().get());
|
||||
}
|
||||
|
||||
settingsInner = String.format("size(%s);", argJoiner.toString());
|
||||
}
|
||||
|
||||
|
||||
String newCode = String.format(settingsOuterTemplate, settingsInner);
|
||||
|
||||
classBodyWriter.addEmptyLine();
|
||||
classBodyWriter.addCodeLine(newCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the main method.
|
||||
*
|
||||
* @param footerWriter The writer into which the footer should be written.
|
||||
* @param params The parameters for the rewrite.
|
||||
* @param resultBuilder Builder for reporting out results to the caller.
|
||||
*/
|
||||
private void writeMain(PrintWriterWithEditGen footerWriter, RewriteParams params,
|
||||
RewriteResultBuilder resultBuilder) {
|
||||
|
||||
footerWriter.addEmptyLine();
|
||||
footerWriter.addCodeLine(indent1 + "static public void main(String[] passedArgs) {");
|
||||
footerWriter.addCode(indent2 + "String[] appletArgs = new String[] { ");
|
||||
|
||||
{ // assemble line with applet args
|
||||
if (Preferences.getBoolean("export.application.fullscreen")) {
|
||||
footerWriter.addCode("\"" + PApplet.ARGS_FULL_SCREEN + "\", ");
|
||||
|
||||
String bgColor = Preferences.get("run.present.bgcolor");
|
||||
footerWriter.addCode("\"" + PApplet.ARGS_BGCOLOR + "=" + bgColor + "\", ");
|
||||
|
||||
if (Preferences.getBoolean("export.application.stop")) {
|
||||
String stopColor = Preferences.get("run.present.stop.color");
|
||||
footerWriter.addCode("\"" + PApplet.ARGS_STOP_COLOR + "=" + stopColor + "\", ");
|
||||
} else {
|
||||
footerWriter.addCode("\"" + PApplet.ARGS_HIDE_STOP + "\", ");
|
||||
}
|
||||
}
|
||||
footerWriter.addCode("\"" + params.getSketchName() + "\"");
|
||||
}
|
||||
|
||||
footerWriter.addCodeLine(" };");
|
||||
|
||||
footerWriter.addCodeLine(indent2 + "if (passedArgs != null) {");
|
||||
footerWriter.addCodeLine(indent3 + "PApplet.main(concat(appletArgs, passedArgs));");
|
||||
footerWriter.addCodeLine(indent2 + "} else {");
|
||||
footerWriter.addCodeLine(indent3 + "PApplet.main(appletArgs);");
|
||||
footerWriter.addCodeLine(indent2 + "}");
|
||||
footerWriter.addCodeLine(indent1 + "}");
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the end of the class body for the footer.
|
||||
*
|
||||
* @param footerWriter The writer into which the footer should be written.
|
||||
* @param params The parameters for the rewrite.
|
||||
* @param resultBuilder Builder for reporting out results to the caller.
|
||||
*/
|
||||
private void writeClassFooter(PrintWriterWithEditGen footerWriter, RewriteParams params,
|
||||
RewriteResultBuilder resultBuilder) {
|
||||
|
||||
footerWriter.addCodeLine("}");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -25,8 +25,6 @@ import org.antlr.v4.runtime.BaseErrorListener;
|
||||
import org.antlr.v4.runtime.RecognitionException;
|
||||
import org.antlr.v4.runtime.Recognizer;
|
||||
|
||||
import processing.mode.java.preproc.SourceEmitter;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
@@ -100,4 +98,31 @@ public class PdeIssueEmitter extends BaseErrorListener {
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple interface for strategy which can emit the full body of a processing sketch.
|
||||
*/
|
||||
public static interface SourceEmitter {
|
||||
|
||||
/**
|
||||
* Get the full body of the processing sketch.
|
||||
*
|
||||
* @return String processing sketch source code across all tabs.
|
||||
*/
|
||||
String getSource();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for listener that responds to issues reported by the preprocessor.
|
||||
*/
|
||||
public static interface PdePreprocessIssueListener {
|
||||
|
||||
/**
|
||||
* Callback to invoke when an issue is encountered in preprocesing.
|
||||
*
|
||||
* @param issue Description of the issue.
|
||||
*/
|
||||
void onIssue(PdePreprocessIssue issue);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
package processing.mode.java.preproc.issue;
|
||||
|
||||
import processing.mode.java.preproc.issue.PdePreprocessIssue;
|
||||
|
||||
public interface PdePreprocessIssueListener {
|
||||
|
||||
void onIssue(PdePreprocessIssue issue);
|
||||
|
||||
}
|
||||
@@ -662,10 +662,8 @@ public class Runner implements MessageConsumer {
|
||||
|
||||
|
||||
protected Connector findConnector(String connectorName) {
|
||||
// List connectors =
|
||||
// com.sun.jdi.Bootstrap.virtualMachineManager().allConnectors();
|
||||
List<Connector> connectors =
|
||||
org.eclipse.jdi.Bootstrap.virtualMachineManager().allConnectors();
|
||||
com.sun.jdi.Bootstrap.virtualMachineManager().allConnectors();
|
||||
|
||||
// // debug: code to list available connectors
|
||||
// Iterator iter2 = connectors.iterator();
|
||||
|
||||
@@ -23,6 +23,7 @@ package processing.mode.java.tweak;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.Comparator;
|
||||
import java.util.Locale;
|
||||
|
||||
@@ -171,7 +172,7 @@ public class Handle {
|
||||
|
||||
} else if ("float".equals(type)) {
|
||||
BigDecimal bd = new BigDecimal(value.floatValue());
|
||||
bd = bd.setScale(decimalPlaces, BigDecimal.ROUND_HALF_UP);
|
||||
bd = bd.setScale(decimalPlaces, RoundingMode.HALF_UP);
|
||||
newValue = bd.floatValue();
|
||||
strNewValue = String.format(Locale.US, textFormat, newValue.floatValue());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user