Search in sources :

Example 1 with JavaMode

use of processing.mode.java.JavaMode in project processing by processing.

the class PreprocessingService method preprocessSketch.

/// --------------------------------------------------------------------------
private PreprocessedSketch preprocessSketch(PreprocessedSketch prevResult) {
    boolean firstCheck = prevResult == null;
    PreprocessedSketch.Builder result = new PreprocessedSketch.Builder();
    List<ImportStatement> codeFolderImports = result.codeFolderImports;
    List<ImportStatement> programImports = result.programImports;
    JavaMode javaMode = (JavaMode) editor.getMode();
    Sketch sketch = result.sketch = editor.getSketch();
    String className = sketch.getName();
    StringBuilder workBuffer = new StringBuilder();
    // Combine code into one buffer
    IntList tabStartsList = new IntList();
    for (SketchCode sc : sketch.getCode()) {
        if (sc.isExtension("pde")) {
            tabStartsList.append(workBuffer.length());
            try {
                workBuffer.append(sc.getDocumentText());
            } catch (BadLocationException e) {
                e.printStackTrace();
            }
            workBuffer.append('\n');
        }
    }
    result.tabStartOffsets = tabStartsList.array();
    String pdeStage = result.pdeCode = workBuffer.toString();
    boolean reloadCodeFolder = firstCheck || codeFolderChanged.getAndSet(false);
    boolean reloadLibraries = firstCheck || librariesChanged.getAndSet(false);
    // Core and default imports
    if (coreAndDefaultImports == null) {
        PdePreprocessor p = editor.createPreprocessor(null);
        coreAndDefaultImports = buildCoreAndDefaultImports(p);
    }
    result.coreAndDefaultImports.addAll(coreAndDefaultImports);
    // Prepare code folder imports
    if (reloadCodeFolder) {
        codeFolderImports.addAll(buildCodeFolderImports(sketch));
    } else {
        codeFolderImports.addAll(prevResult.codeFolderImports);
    }
    // TODO: convert unicode escapes to chars
    SourceUtils.scrubCommentsAndStrings(workBuffer);
    Mode sketchMode = PdePreprocessor.parseMode(workBuffer);
    // Prepare transforms to convert pde code into parsable code
    TextTransform toParsable = new TextTransform(pdeStage);
    toParsable.addAll(SourceUtils.insertImports(coreAndDefaultImports));
    toParsable.addAll(SourceUtils.insertImports(codeFolderImports));
    toParsable.addAll(SourceUtils.parseProgramImports(workBuffer, programImports));
    toParsable.addAll(SourceUtils.replaceTypeConstructors(workBuffer));
    toParsable.addAll(SourceUtils.replaceHexLiterals(workBuffer));
    toParsable.addAll(SourceUtils.wrapSketch(sketchMode, className, workBuffer.length()));
    {
        // Refresh sketch classloader and classpath if imports changed
        if (javaRuntimeClassPath == null) {
            javaRuntimeClassPath = buildJavaRuntimeClassPath();
            sketchModeClassPath = buildModeClassPath(javaMode, false);
            searchModeClassPath = buildModeClassPath(javaMode, true);
        }
        if (reloadLibraries) {
            coreLibraryClassPath = buildCoreLibraryClassPath(javaMode);
        }
        boolean rebuildLibraryClassPath = reloadLibraries || checkIfImportsChanged(programImports, prevResult.programImports);
        if (rebuildLibraryClassPath) {
            sketchLibraryClassPath = buildSketchLibraryClassPath(javaMode, programImports);
            searchLibraryClassPath = buildSearchLibraryClassPath(javaMode);
        }
        boolean rebuildClassPath = reloadCodeFolder || rebuildLibraryClassPath || prevResult.classLoader == null || prevResult.classPath == null || prevResult.classPathArray == null || prevResult.searchClassPathArray == null;
        if (reloadCodeFolder) {
            codeFolderClassPath = buildCodeFolderClassPath(sketch);
        }
        if (rebuildClassPath) {
            {
                // Sketch class path
                List<String> sketchClassPath = new ArrayList<>();
                sketchClassPath.addAll(javaRuntimeClassPath);
                sketchClassPath.addAll(sketchModeClassPath);
                sketchClassPath.addAll(sketchLibraryClassPath);
                sketchClassPath.addAll(coreLibraryClassPath);
                sketchClassPath.addAll(codeFolderClassPath);
                String[] classPathArray = sketchClassPath.stream().toArray(String[]::new);
                URL[] urlArray = Arrays.stream(classPathArray).map(path -> {
                    try {
                        return Paths.get(path).toUri().toURL();
                    } catch (MalformedURLException e) {
                        Messages.loge("malformed URL when preparing sketch classloader", e);
                        return null;
                    }
                }).filter(url -> url != null).toArray(URL[]::new);
                result.classLoader = new URLClassLoader(urlArray, null);
                result.classPath = classPathFactory.createFromPaths(classPathArray);
                result.classPathArray = classPathArray;
            }
            {
                // Search class path
                List<String> searchClassPath = new ArrayList<>();
                searchClassPath.addAll(javaRuntimeClassPath);
                searchClassPath.addAll(searchModeClassPath);
                searchClassPath.addAll(searchLibraryClassPath);
                searchClassPath.addAll(coreLibraryClassPath);
                searchClassPath.addAll(codeFolderClassPath);
                result.searchClassPathArray = searchClassPath.stream().toArray(String[]::new);
            }
        } else {
            result.classLoader = prevResult.classLoader;
            result.classPath = prevResult.classPath;
            result.searchClassPathArray = prevResult.searchClassPathArray;
            result.classPathArray = prevResult.classPathArray;
        }
    }
    {
        // Check for missing braces
        List<JavaProblem> missingBraceProblems = SourceUtils.checkForMissingBraces(workBuffer, result.tabStartOffsets);
        if (!missingBraceProblems.isEmpty()) {
            result.missingBraceProblems.addAll(missingBraceProblems);
            result.hasSyntaxErrors = true;
        }
    }
    // Transform code to parsable state
    String parsableStage = toParsable.apply();
    OffsetMapper parsableMapper = toParsable.getMapper();
    // Create intermediate AST for advanced preprocessing
    CompilationUnit parsableCU = makeAST(parser, parsableStage.toCharArray(), COMPILER_OPTIONS);
    // Prepare advanced transforms which operate on AST
    TextTransform toCompilable = new TextTransform(parsableStage);
    toCompilable.addAll(SourceUtils.preprocessAST(parsableCU));
    // Transform code to compilable state
    String compilableStage = toCompilable.apply();
    OffsetMapper compilableMapper = toCompilable.getMapper();
    char[] compilableStageChars = compilableStage.toCharArray();
    // Create compilable AST to get syntax problems
    CompilationUnit compilableCU = makeAST(parser, compilableStageChars, COMPILER_OPTIONS);
    // Get syntax problems from compilable AST
    result.hasSyntaxErrors |= Arrays.stream(compilableCU.getProblems()).anyMatch(IProblem::isError);
    // Generate bindings after getting problems - avoids
    // 'missing type' errors when there are syntax problems
    CompilationUnit bindingsCU = makeASTWithBindings(parser, compilableStageChars, COMPILER_OPTIONS, className, result.classPathArray);
    // Get compilation problems
    List<IProblem> bindingsProblems = Arrays.asList(bindingsCU.getProblems());
    result.hasCompilationErrors = bindingsProblems.stream().anyMatch(IProblem::isError);
    // Update builder
    result.offsetMapper = parsableMapper.thenMapping(compilableMapper);
    result.javaCode = compilableStage;
    result.compilationUnit = bindingsCU;
    // Build it
    return result.build();
}
Also used : JavaMode(processing.mode.java.JavaMode) Arrays(java.util.Arrays) CompilationUnit(org.eclipse.jdt.core.dom.CompilationUnit) URL(java.net.URL) PdePreprocessor(processing.mode.java.preproc.PdePreprocessor) TimeoutException(java.util.concurrent.TimeoutException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) ArrayList(java.util.ArrayList) URLClassLoader(java.net.URLClassLoader) StringList(processing.data.StringList) Map(java.util.Map) JavaEditor(processing.mode.java.JavaEditor) StreamSupport(java.util.stream.StreamSupport) Mode(processing.mode.java.preproc.PdePreprocessor.Mode) SketchCode(processing.app.SketchCode) SketchException(processing.app.SketchException) Library(processing.app.Library) Messages(processing.app.Messages) Sketch(processing.app.Sketch) ClassPathFactory(com.google.classpath.ClassPathFactory) MalformedURLException(java.net.MalformedURLException) JavaCore(org.eclipse.jdt.core.JavaCore) Set(java.util.Set) BlockingQueue(java.util.concurrent.BlockingQueue) BadLocationException(javax.swing.text.BadLocationException) CopyOnWriteArraySet(java.util.concurrent.CopyOnWriteArraySet) Collectors(java.util.stream.Collectors) File(java.io.File) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) ArrayBlockingQueue(java.util.concurrent.ArrayBlockingQueue) IntList(processing.data.IntList) List(java.util.List) ASTParser(org.eclipse.jdt.core.dom.ASTParser) Paths(java.nio.file.Paths) OffsetMapper(processing.mode.java.pdex.TextTransform.OffsetMapper) AST(org.eclipse.jdt.core.dom.AST) IProblem(org.eclipse.jdt.core.compiler.IProblem) Collections(java.util.Collections) Util(processing.app.Util) MalformedURLException(java.net.MalformedURLException) SketchCode(processing.app.SketchCode) ArrayList(java.util.ArrayList) URL(java.net.URL) OffsetMapper(processing.mode.java.pdex.TextTransform.OffsetMapper) ArrayList(java.util.ArrayList) StringList(processing.data.StringList) IntList(processing.data.IntList) List(java.util.List) CompilationUnit(org.eclipse.jdt.core.dom.CompilationUnit) JavaMode(processing.mode.java.JavaMode) Mode(processing.mode.java.preproc.PdePreprocessor.Mode) IProblem(org.eclipse.jdt.core.compiler.IProblem) JavaMode(processing.mode.java.JavaMode) IntList(processing.data.IntList) URLClassLoader(java.net.URLClassLoader) Sketch(processing.app.Sketch) PdePreprocessor(processing.mode.java.preproc.PdePreprocessor) BadLocationException(javax.swing.text.BadLocationException)

Aggregations

ClassPathFactory (com.google.classpath.ClassPathFactory)1 File (java.io.File)1 MalformedURLException (java.net.MalformedURLException)1 URL (java.net.URL)1 URLClassLoader (java.net.URLClassLoader)1 Paths (java.nio.file.Paths)1 ArrayList (java.util.ArrayList)1 Arrays (java.util.Arrays)1 Collections (java.util.Collections)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Map (java.util.Map)1 Set (java.util.Set)1 ArrayBlockingQueue (java.util.concurrent.ArrayBlockingQueue)1 BlockingQueue (java.util.concurrent.BlockingQueue)1 CompletableFuture (java.util.concurrent.CompletableFuture)1 CopyOnWriteArraySet (java.util.concurrent.CopyOnWriteArraySet)1 ExecutionException (java.util.concurrent.ExecutionException)1 TimeUnit (java.util.concurrent.TimeUnit)1 TimeoutException (java.util.concurrent.TimeoutException)1