use of processing.app.SketchException in project processing by processing.
the class Commander method statusError.
public void statusError(Exception exception) {
if (exception instanceof SketchException) {
SketchException re = (SketchException) exception;
int codeIndex = re.getCodeIndex();
if (codeIndex != -1) {
// format the runner exception like emacs
//blah.java:2:10:2:13: Syntax Error: This is a big error message
// Emacs doesn't like the double line thing coming from Java
// https://github.com/processing/processing/issues/2158
String filename = sketch.getCode(codeIndex).getFileName();
int line = re.getCodeLine() + 1;
int column = re.getCodeColumn() + 1;
//if (column == -1) column = 0;
// TODO if column not specified, should just select the whole line.
// But what's the correct syntax for that?
systemErr.println(filename + ":" + line + ":" + column + ":" + line + ":" + column + ":" + " " + re.getMessage());
} else {
// no line number, pass the trace along to the user
exception.printStackTrace();
}
} else {
exception.printStackTrace();
}
}
use of processing.app.SketchException in project processing by processing.
the class JavaBuild method placeException.
/**
* Map an error from a set of processed .java files back to its location
* in the actual sketch.
* @param message The error message.
* @param filename The .java file where the exception was found.
* @param line Line number of the .java file for the exception (0-indexed!)
* @return A RunnerException to be sent to the editor, or null if it wasn't
* possible to place the exception to the sketch code.
*/
public SketchException placeException(String message, String dotJavaFilename, int dotJavaLine) {
//-1;
int codeIndex = 0;
int codeLine = -1;
// first check to see if it's a .java file
for (int i = 0; i < sketch.getCodeCount(); i++) {
SketchCode code = sketch.getCode(i);
if (code.isExtension("java")) {
if (dotJavaFilename.equals(code.getFileName())) {
codeIndex = i;
codeLine = dotJavaLine;
return new SketchException(message, codeIndex, codeLine);
}
}
}
// If not the preprocessed file at this point, then need to get out
if (!dotJavaFilename.equals(sketch.getName() + ".java")) {
return null;
}
// if it's not a .java file, codeIndex will still be 0
// this section searches through the list of .pde files
codeIndex = 0;
for (int i = 0; i < sketch.getCodeCount(); i++) {
SketchCode code = sketch.getCode(i);
if (code.isExtension("pde")) {
// System.out.println("looking for line " + dotJavaLine);
if (code.getPreprocOffset() <= dotJavaLine) {
codeIndex = i;
// System.out.println("i'm thinkin file " + i);
codeLine = dotJavaLine - code.getPreprocOffset();
}
}
}
// changed for 0194 for compile errors, but...
return new SketchException(message, codeIndex, codeLine, -1, false);
}
use of processing.app.SketchException in project processing by processing.
the class JavaBuild method preprocess.
/**
* @param srcFolder location where the .java source files will be placed
* @param packageName null, or the package name that should be used as default
* @param preprocessor the preprocessor object ready to do the work
* @return main PApplet class name found during preprocess, or null if error
* @throws SketchException
*/
public String preprocess(File srcFolder, String packageName, PdePreprocessor preprocessor, boolean sizeWarning) throws SketchException {
// make sure the user isn't playing "hide the sketch folder"
sketch.ensureExistence();
// System.out.println("srcFolder is " + srcFolder);
classPath = binFolder.getAbsolutePath();
// figure out the contents of the code folder to see if there
// are files that need to be added to the imports
StringList codeFolderPackages = null;
if (sketch.hasCodeFolder()) {
File codeFolder = sketch.getCodeFolder();
javaLibraryPath = codeFolder.getAbsolutePath();
// get a list of .jar files in the "code" folder
// (class files in subfolders should also be picked up)
String codeFolderClassPath = Util.contentsToClassPath(codeFolder);
// append the jar files in the code folder to the class path
classPath += File.pathSeparator + codeFolderClassPath;
// get list of packages found in those jars
codeFolderPackages = Util.packageListFromClassPath(codeFolderClassPath);
} else {
javaLibraryPath = "";
}
// 1. concatenate all .pde files to the 'main' pde
// store line number for starting point of each code bit
StringBuilder bigCode = new StringBuilder();
int bigCount = 0;
for (SketchCode sc : sketch.getCode()) {
if (sc.isExtension("pde")) {
sc.setPreprocOffset(bigCount);
bigCode.append(sc.getProgram());
bigCode.append('\n');
bigCount += sc.getLineCount();
}
}
// initSketchSize() sets the internal sketchWidth/Height/Renderer vars
// in the preprocessor. Those are used in preproc.write() so that they
// can be used to add methods (settings() or sketchXxxx())
//String[] sizeParts =
SurfaceInfo sizeInfo = preprocessor.initSketchSize(sketch.getMainProgram(), sizeWarning);
if (sizeInfo == null) {
// An error occurred while trying to pull out the size, so exit here
return null;
}
// by writeFooter() when it emits the settings() method.
if (sizeInfo != null && sizeInfo.hasSettings()) {
// String sizeStatement = sizeInfo.getStatement();
for (String stmt : sizeInfo.getStatements()) {
//System.out.format("size stmt is '%s'%n", sizeStatement);
// Don't remove newlines (and while you're at it, just keep spaces)
// https://github.com/processing/processing/issues/3654
stmt = stmt.trim();
int index = bigCode.indexOf(stmt);
if (index != -1) {
bigCode.delete(index, index + stmt.length());
} else {
// TODO remove once we hit final; but prevent an exception like in
// https://github.com/processing/processing/issues/3531
System.err.format("Error removing '%s' from the code.", stmt);
}
}
}
PreprocessorResult result;
try {
File outputFolder = (packageName == null) ? srcFolder : new File(srcFolder, packageName.replace('.', '/'));
outputFolder.mkdirs();
// Base.openFolder(outputFolder);
final File java = new File(outputFolder, sketch.getName() + ".java");
final PrintWriter stream = new PrintWriter(new FileWriter(java));
try {
result = preprocessor.write(stream, bigCode.toString(), codeFolderPackages);
} finally {
stream.close();
}
} catch (FileNotFoundException fnfe) {
fnfe.printStackTrace();
String msg = "Build folder disappeared or could not be written";
throw new SketchException(msg);
} catch (antlr.RecognitionException re) {
// re also returns a column that we're not bothering with for now
// first assume that it's the main file
// int errorFile = 0;
int errorLine = re.getLine() - 1;
// then search through for anyone else whose preprocName is null,
// since they've also been combined into the main pde.
int errorFile = findErrorFile(errorLine);
// System.out.println("error line is " + errorLine + ", file is " + errorFile);
errorLine -= sketch.getCode(errorFile).getPreprocOffset();
// System.out.println(" preproc offset for that file: " + sketch.getCode(errorFile).getPreprocOffset());
// System.out.println("i found this guy snooping around..");
// System.out.println("whatcha want me to do with 'im boss?");
// System.out.println(errorLine + " " + errorFile + " " + code[errorFile].getPreprocOffset());
String msg = re.getMessage();
if (msg.contains("expecting RCURLY")) {
// useful for other similar situations).
throw new SketchException("Found one too many { characters " + "without a } to match it.", errorFile, errorLine, re.getColumn(), false);
}
if (msg.contains("expecting LCURLY")) {
System.err.println(msg);
String suffix = ".";
String[] m = PApplet.match(msg, "found ('.*')");
if (m != null) {
suffix = ", not " + m[1] + ".";
}
throw new SketchException("Was expecting a { character" + suffix, errorFile, errorLine, re.getColumn(), false);
}
if (msg.indexOf("expecting RBRACK") != -1) {
System.err.println(msg);
throw new SketchException("Syntax error, " + "maybe a missing ] character?", errorFile, errorLine, re.getColumn(), false);
}
if (msg.indexOf("expecting SEMI") != -1) {
System.err.println(msg);
throw new SketchException("Syntax error, " + "maybe a missing semicolon?", errorFile, errorLine, re.getColumn(), false);
}
if (msg.indexOf("expecting RPAREN") != -1) {
System.err.println(msg);
throw new SketchException("Syntax error, " + "maybe a missing right parenthesis?", errorFile, errorLine, re.getColumn(), false);
}
if (msg.indexOf("preproc.web_colors") != -1) {
throw new SketchException("A web color (such as #ffcc00) " + "must be six digits.", errorFile, errorLine, re.getColumn(), false);
}
//System.out.println("msg is " + msg);
throw new SketchException(msg, errorFile, errorLine, re.getColumn(), false);
} catch (antlr.TokenStreamRecognitionException tsre) {
// while this seems to store line and column internally,
// there doesn't seem to be a method to grab it..
// so instead it's done using a regexp
// System.err.println("and then she tells me " + tsre.toString());
// TODO not tested since removing ORO matcher.. ^ could be a problem
String mess = "^line (\\d+):(\\d+):\\s";
String[] matches = PApplet.match(tsre.toString(), mess);
if (matches != null) {
int errorLine = Integer.parseInt(matches[1]) - 1;
int errorColumn = Integer.parseInt(matches[2]);
int errorFile = 0;
for (int i = 1; i < sketch.getCodeCount(); i++) {
SketchCode sc = sketch.getCode(i);
if (sc.isExtension("pde") && (sc.getPreprocOffset() < errorLine)) {
errorFile = i;
}
}
errorLine -= sketch.getCode(errorFile).getPreprocOffset();
throw new SketchException(tsre.getMessage(), errorFile, errorLine, errorColumn);
} else {
// this is bad, defaults to the main class.. hrm.
String msg = tsre.toString();
throw new SketchException(msg, 0, -1, -1);
}
} catch (SketchException pe) {
// get lost in the more general "Exception" handler below.
throw pe;
} catch (Exception ex) {
// TODO better method for handling this?
System.err.println("Uncaught exception type:" + ex.getClass());
ex.printStackTrace();
throw new SketchException(ex.toString());
}
// grab the imports from the code just preprocessed
importedLibraries = new ArrayList<Library>();
Library core = mode.getCoreLibrary();
if (core != null) {
importedLibraries.add(core);
classPath += core.getClassPath();
javaLibraryPath += File.pathSeparator + core.getNativePath();
}
// System.out.println("extra imports: " + result.extraImports);
for (String item : result.extraImports) {
// System.out.println("item = '" + item + "'");
// remove things up to the last dot
int dot = item.lastIndexOf('.');
// http://dev.processing.org/bugs/show_bug.cgi?id=1145
String entry = (dot == -1) ? item : item.substring(0, dot);
if (item.startsWith("static ")) {
// import static - https://github.com/processing/processing/issues/8
// Remove more stuff.
int dot2 = item.lastIndexOf('.');
entry = entry.substring(7, (dot2 == -1) ? entry.length() : dot2);
// System.out.println(entry);
}
// System.out.println("library searching for " + entry);
Library library = mode.getLibrary(entry);
if (library != null) {
if (!importedLibraries.contains(library)) {
importedLibraries.add(library);
classPath += library.getClassPath();
javaLibraryPath += File.pathSeparator + library.getNativePath();
}
} else {
boolean found = false;
// import, don't show an error for it.
if (codeFolderPackages != null) {
String itemPkg = entry;
for (String pkg : codeFolderPackages) {
if (pkg.equals(itemPkg)) {
found = true;
break;
}
}
}
if (ignorableImport(entry + '.')) {
found = true;
}
if (!found) {
System.err.println("No library found for " + entry);
}
}
}
// PApplet.println(PApplet.split(libraryPath, File.pathSeparatorChar));
// Finally, add the regular Java CLASSPATH. This contains everything
// imported by the PDE itself (core.jar, pde.jar, quaqua.jar) which may
// in fact be more of a problem.
String javaClassPath = System.getProperty("java.class.path");
// Remove quotes if any.. A messy (and frequent) Windows problem
if (javaClassPath.startsWith("\"") && javaClassPath.endsWith("\"")) {
javaClassPath = javaClassPath.substring(1, javaClassPath.length() - 1);
}
classPath += File.pathSeparator + javaClassPath;
for (SketchCode sc : sketch.getCode()) {
if (sc.isExtension("java")) {
// In most cases, no pre-processing services necessary for Java files.
// Just write the the contents of 'program' to a .java file
// into the build directory. However, if a default package is being
// used (as in Android), and no package is specified in the source,
// then we need to move this code to the same package as the sketch.
// Otherwise, the class may not be found, or at a minimum, the default
// access across the packages will mean that things behave incorrectly.
// For instance, desktop code that uses a .java file with no packages,
// will be fine with the default access, but since Android's PApplet
// requires a package, code from that (default) package (such as the
// PApplet itself) won't have access to methods/variables from the
// package-less .java file (unless they're all marked public).
String filename = sc.getFileName();
try {
String javaCode = sc.getProgram();
String[] packageMatch = PApplet.match(javaCode, PACKAGE_REGEX);
if (packageMatch == null && packageName == null) {
sc.copyTo(new File(srcFolder, filename));
} else {
if (packageMatch == null) {
// use the default package name, since mixing with package-less code will break
packageMatch = new String[] { "", packageName };
// add the package name to the source before writing it
javaCode = "package " + packageName + ";" + javaCode;
}
File packageFolder = new File(srcFolder, packageMatch[1].replace('.', File.separatorChar));
packageFolder.mkdirs();
Util.saveFile(javaCode, new File(packageFolder, filename));
}
} catch (IOException e) {
e.printStackTrace();
String msg = "Problem moving " + filename + " to the build folder";
throw new SketchException(msg);
}
} else if (sc.isExtension("pde")) {
// The compiler and runner will need this to have a proper offset
sc.addPreprocOffset(result.headerOffset);
}
}
foundMain = preprocessor.hasMethod("main");
return result.className;
}
use of processing.app.SketchException in project processing by processing.
the class Editor method statusError.
/**
* Show an exception in the editor status bar.
*/
public void statusError(Exception e) {
e.printStackTrace();
if (e instanceof SketchException) {
SketchException re = (SketchException) e;
if (re.hasCodeIndex()) {
sketch.setCurrentCode(re.getCodeIndex());
}
if (re.hasCodeLine()) {
int line = re.getCodeLine();
// subtract one from the end so that the \n ain't included
if (line >= textarea.getLineCount()) {
// The error is at the end of this current chunk of code,
// so the last line needs to be selected.
line = textarea.getLineCount() - 1;
if (textarea.getLineText(line).length() == 0) {
// The last line may be zero length, meaning nothing to select.
// If so, back up one more line.
line--;
}
}
if (line < 0 || line >= textarea.getLineCount()) {
System.err.println("Bad error line: " + line);
} else {
textarea.select(textarea.getLineStartOffset(line), textarea.getLineStopOffset(line) - 1);
}
}
}
// Since this will catch all Exception types, spend some time figuring
// out which kind and try to give a better error message to the user.
String mess = e.getMessage();
if (mess != null) {
String javaLang = "java.lang.";
if (mess.indexOf(javaLang) == 0) {
mess = mess.substring(javaLang.length());
}
// The phrase "RuntimeException" isn't useful for most users
String rxString = "RuntimeException: ";
if (mess.startsWith(rxString)) {
mess = mess.substring(rxString.length());
}
// This is just confusing for most PDE users (save it for Eclipse users)
String illString = "IllegalArgumentException: ";
if (mess.startsWith(illString)) {
mess = mess.substring(illString.length());
}
// This is confusing and common with the size() and fullScreen() changes
String illState = "IllegalStateException: ";
if (mess.startsWith(illState)) {
mess = mess.substring(illState.length());
}
statusError(mess);
}
// e.printStackTrace();
}
use of processing.app.SketchException in project processing by processing.
the class PdePreprocessor method write.
/**
* preprocesses a pde file and writes out a java file
* @return the class name of the exported Java
*/
private String write(final String program, final PrintWriter stream) throws SketchException, RecognitionException, TokenStreamException {
// Match on the uncommented version, otherwise code inside comments used
// http://code.google.com/p/processing/issues/detail?id=1404
String uncomment = scrubComments(program);
PdeRecognizer parser = createParser(program);
Mode mode = parseMode(uncomment);
switch(mode) {
case JAVA:
try {
final PrintStream saved = System.err;
try {
// throw away stderr for this tentative parse
System.setErr(new PrintStream(new ByteArrayOutputStream()));
parser.javaProgram();
} finally {
System.setErr(saved);
}
setMode(Mode.JAVA);
} catch (Exception e) {
// I can't figure out any other way of resetting the parser.
parser = createParser(program);
parser.pdeProgram();
}
break;
case ACTIVE:
setMode(Mode.ACTIVE);
parser.activeProgram();
break;
case STATIC:
parser.pdeProgram();
break;
}
// set up the AST for traversal by PdeEmitter
//
ASTFactory factory = new ASTFactory();
AST parserAST = parser.getAST();
AST rootNode = factory.create(ROOT_ID, "AST ROOT");
rootNode.setFirstChild(parserAST);
makeSimpleMethodsPublic(rootNode);
// unclear if this actually works, but it's worth a shot
//
//((CommonAST)parserAST).setVerboseStringConversion(
// true, parser.getTokenNames());
// (made to use the static version because of jikes 1.22 warning)
BaseAST.setVerboseStringConversion(true, parser.getTokenNames());
final String className;
if (mode == Mode.JAVA) {
// if this is an advanced program, the classname is already defined.
className = getFirstClassName(parserAST);
} else {
className = this.name;
}
//
if (className == null)
return null;
// debug
if (false) {
final StringWriter buf = new StringWriter();
final PrintWriter bufout = new PrintWriter(buf);
writeDeclaration(bufout, className);
new PdeEmitter(this, bufout).print(rootNode);
writeFooter(bufout, className);
debugAST(rootNode, true);
System.err.println(buf.toString());
}
writeDeclaration(stream, className);
new PdeEmitter(this, stream).print(rootNode);
writeFooter(stream, className);
// be viewed usefully with Mozilla or IE
if (Preferences.getBoolean("preproc.output_parse_tree")) {
writeParseTree("parseTree.xml", parserAST);
}
return className;
}
Aggregations