From 78b8089000bf7ffa0506dad2f8825a93f47136ee Mon Sep 17 00:00:00 2001 From: A Pottinger Date: Sun, 25 Jul 2021 10:31:11 -0700 Subject: [PATCH] Working with packages but no error correction in java files. --- java/src/processing/mode/java/Compiler.java | 1 - .../processing/mode/java/PreprocService.java | 135 ++++++++++++++++-- .../java/preproc/PdeParseTreeListener.java | 4 - .../mode/java/preproc/Processing.g4 | 4 +- 4 files changed, 128 insertions(+), 16 deletions(-) diff --git a/java/src/processing/mode/java/Compiler.java b/java/src/processing/mode/java/Compiler.java index 94448bf56..628382a08 100644 --- a/java/src/processing/mode/java/Compiler.java +++ b/java/src/processing/mode/java/Compiler.java @@ -74,7 +74,6 @@ public class Compiler { String[] sourceFiles = Util.listFiles(build.getSrcFolder(), false, ".java"); String[] command = PApplet.concat(baseCommand, sourceFiles); - //PApplet.println(command); try { // Load errors into a local StringBuilder diff --git a/java/src/processing/mode/java/PreprocService.java b/java/src/processing/mode/java/PreprocService.java index ae39558ff..ba92a0210 100644 --- a/java/src/processing/mode/java/PreprocService.java +++ b/java/src/processing/mode/java/PreprocService.java @@ -21,7 +21,11 @@ along with this program; if not, write to the Free Software Foundation, Inc. package processing.mode.java; import java.io.File; +import java.io.IOException; import java.io.StringWriter; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -48,6 +52,9 @@ import org.eclipse.jdt.core.compiler.IProblem; import org.eclipse.jdt.core.dom.AST; import org.eclipse.jdt.core.dom.ASTParser; import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.FileASTRequestor; +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IType; import processing.app.Messages; import processing.app.Sketch; @@ -346,9 +353,10 @@ public class PreprocService { // Combine code into one buffer int numLines = 1; IntList tabStartsList = new IntList(); + List javaFiles = new ArrayList<>(); List tabLineStarts = new ArrayList<>(); for (SketchCode sc : sketch.getCode()) { - if (sc.isExtension("pde") || sc.isExtension("java")) { + if (sc.isExtension("pde")) { tabStartsList.append(workBuffer.length()); tabLineStarts.add(numLines); @@ -367,6 +375,8 @@ public class PreprocService { String newPieceBuilt = newPiece.toString(); numLines += SourceUtil.getCount(newPieceBuilt, "\n"); workBuffer.append(newPieceBuilt); + } else if (sc.isExtension("java")) { + javaFiles.add(sc); } } result.tabStartOffsets = tabStartsList.array(); @@ -490,14 +500,21 @@ public class PreprocService { // Generate bindings after getting problems - avoids // 'missing type' errors when there are syntax problems - parser.setSource(compilableStageChars); - parser.setKind(ASTParser.K_COMPILATION_UNIT); - parser.setCompilerOptions(COMPILER_OPTIONS); - parser.setStatementsRecovery(true); - parser.setUnitName(className); - parser.setEnvironment(result.classPathArray, null, null, false); - parser.setResolveBindings(true); - CompilationUnit bindingsCU = (CompilationUnit) parser.createAST(null); + CompilationUnit bindingsCU; + if (javaFiles.size() == 0) { + bindingsCU = compileInMemory( + compilableStage, + className, + result.classPathArray + ); + } else { + bindingsCU = compileFromDisk( + compilableStage, + className, + result.classPathArray, + javaFiles + ); + } // Get compilation problems List bindingsProblems = Arrays.asList(bindingsCU.getProblems()); @@ -513,6 +530,106 @@ public class PreprocService { return result.build(); } + /// FINAL COMPILATION ------------------------------------------------------- + + private CompilationUnit compileInMemory(String compilableStage, + String className, String[] classPathArray) { + + parser.setSource(compilableStage.toCharArray()); + parser.setKind(ASTParser.K_COMPILATION_UNIT); + parser.setCompilerOptions(COMPILER_OPTIONS); + parser.setStatementsRecovery(true); + parser.setUnitName(className); + parser.setEnvironment(classPathArray, null, null, false); + parser.setResolveBindings(true); + return (CompilationUnit) parser.createAST(null); + } + + private CompilationUnit compileFromDisk(String compilableStage, + String className, String[] classPathArray, List javaFiles) { + + List temporaryFilesList = new ArrayList<>(); + + // Prepare preprocessor + parser.setKind(ASTParser.K_COMPILATION_UNIT); + parser.setCompilerOptions(COMPILER_OPTIONS); + parser.setStatementsRecovery(true); + parser.setUnitName(className); + parser.setEnvironment(classPathArray, null, null, false); + parser.setResolveBindings(true); + + // Write compilable processing file + Path mainTemporaryFile = createTemporaryFile(compilableStage); + final String mainSource = mainTemporaryFile.toString(); + temporaryFilesList.add(mainTemporaryFile); + + // Write temporary java files + for (SketchCode javaFile : javaFiles) { + Path newPath = createTemporaryFile(javaFile.getProgram()); + temporaryFilesList.add(newPath); + } + + // Convert paths + int numFiles = temporaryFilesList.size(); + String[] temporaryFilesArray = new String[numFiles]; + for (int i = 0; i < numFiles; i++) { + temporaryFilesArray[i] = temporaryFilesList.get(i).toString(); + } + + // Compile + MutableCompiledUnit compiledHolder = new MutableCompiledUnit();; + parser.createASTs( + temporaryFilesArray, + null, + new String[] {}, + new FileASTRequestor() { + public void acceptAST(String source, CompilationUnit ast) { + if (source.equals(mainSource)) { + compiledHolder.set(ast); + } + } + }, + null + ); + + // Delete + deleteFiles(temporaryFilesList); + + // Return + return compiledHolder.get(); + } + + private Path createTemporaryFile(String content) { + try { + Path tempFile = Files.createTempFile(null, null); + Files.write(tempFile, content.getBytes(StandardCharsets.UTF_8)); + return tempFile; + } catch (IOException e) { + throw new RuntimeException("Cannot write to temporary folder."); + } + } + + private void deleteFiles(List paths) { + try { + for (Path path : paths) { + Files.delete(path); + } + } catch (IOException e) { + throw new RuntimeException("Cannot delete from temporary folder."); + } + } + + private class MutableCompiledUnit { + private CompilationUnit compilationUnit; + + public void set(CompilationUnit newUnit) { + compilationUnit = newUnit; + } + + public CompilationUnit get() { + return compilationUnit; + } + } /// IMPORTS ----------------------------------------------------------------- diff --git a/java/src/processing/mode/java/preproc/PdeParseTreeListener.java b/java/src/processing/mode/java/preproc/PdeParseTreeListener.java index 1fd351f01..70918cc5e 100644 --- a/java/src/processing/mode/java/preproc/PdeParseTreeListener.java +++ b/java/src/processing/mode/java/preproc/PdeParseTreeListener.java @@ -317,10 +317,6 @@ public class PdeParseTreeListener extends ProcessingBaseListener { footerResult = prepareFooter(rewriter, length); } - public void exitPackageDeclaration(ProcessingParser.PackageDeclarationContext ctx) { - delete(ctx.start, ctx.stop); - } - /** * Endpoint for ANTLR to call when finished parsing a method invocatino. * diff --git a/java/src/processing/mode/java/preproc/Processing.g4 b/java/src/processing/mode/java/preproc/Processing.g4 index 6d3e51d38..477b407a1 100644 --- a/java/src/processing/mode/java/preproc/Processing.g4 +++ b/java/src/processing/mode/java/preproc/Processing.g4 @@ -30,12 +30,12 @@ javaProcessingSketch ; staticProcessingSketch - : (importDeclaration | blockStatement)* EOF + : (packageDeclaration | importDeclaration | blockStatement)* EOF ; // active mode, has function definitions activeProcessingSketch - : (importDeclaration | classBodyDeclaration)* EOF + : (packageDeclaration | importDeclaration | classBodyDeclaration)* EOF ; variableDeclaratorId