private void runHints()

in cmdline/processor/src/org/netbeans/modules/jackpot30/cmdline/processor/ProcessorImpl.java [136:262]


    private void runHints() {
        Utils.addExports();

        Trees trees = Trees.instance(processingEnv);
        Level originalLoggerLevel = TOP_LOGGER.getLevel();
        Path toDelete = null;
        try {
            TOP_LOGGER.setLevel(Level.OFF);
            System.setProperty("RepositoryUpdate.increasedLogLevel", "OFF");
            Method getContext = processingEnv.getClass().getDeclaredMethod("getContext");
            Object context = getContext.invoke(processingEnv);
            Method get = context.getClass().getDeclaredMethod("get", Class.class);
            JavaFileManager fileManager = (JavaFileManager) get.invoke(context, JavaFileManager.class);

            if (!(fileManager instanceof StandardJavaFileManager)) {
                processingEnv.getMessager().printMessage(Kind.ERROR, "The file manager is not a StandardJavaFileManager, cannot run Jackpot 3.0.");
                return ;
            }

            setupCache();

            StandardJavaFileManager sfm = (StandardJavaFileManager) fileManager;

            ClassPath bootCP = /*XXX*/Utils.createDefaultBootClassPath();//toClassPath(sfm.getLocation(StandardLocation.PLATFORM_CLASS_PATH));
            ClassPath compileCP = toClassPath(sfm.getLocation(StandardLocation.CLASS_PATH));
            Iterable<? extends File> sourcePathLocation = sfm.getLocation(StandardLocation.SOURCE_PATH);
            ClassPath sourceCP = sourcePathLocation != null ? toClassPath(sourcePathLocation) : inferSourcePath();

            final Map<FileObject, CompilationUnitTree> sourceFiles = new HashMap<>();

            for (Entry<URL, CompilationUnitTree> e : sources.entrySet()) {
                FileObject fo = URLMapper.findFileObject(e.getKey());
                if (fo == null) {
                    //XXX:
                    return ;
                }
                sourceFiles.put(fo, e.getValue());
            }

            URI settingsURI;
            String configurationFileLoc = processingEnv.getOptions().get(CONFIGURATION_OPTION);
            File configurationFile = configurationFileLoc != null ? new File(configurationFileLoc) : null;

            if (configurationFile == null || !configurationFile.canRead()) {
                URL cfg = ProcessorImpl.class.getResource("/org/netbeans/modules/jackpot30/cmdline/processor/cfg_hints.xml");
                Path tmp = Files.createTempFile("cfg_hints", "xml"); //TODO: delete
                try (InputStream cfgIn = cfg.openStream();
                     OutputStream out = Files.newOutputStream(tmp)) {
                    int read;
                    while ((read = cfgIn.read()) != (-1))
                        out.write(read);
                }
                settingsURI = tmp.toUri();
                toDelete = tmp;
            } else {
                settingsURI = configurationFile.toURI();
            }

            HintsSettings settings = HintsSettings.createPreferencesBasedHintsSettings(ToolPreferences.from(settingsURI).getPreferences("hints", "text/x-java"), true, null);

            final Map<HintMetadata, ? extends Collection<? extends HintDescription>> allHints;
            java.io.PrintStream oldErr = System.err;
            try {
                //XXX: TreeUtilities.unenter prints exceptions to stderr on JDK 11, throw the output away:
                System.setErr(new java.io.PrintStream(new java.io.ByteArrayOutputStream()));
                allHints = RulesManager.getInstance().readHints(null, Arrays.asList(bootCP, compileCP, sourceCP), new AtomicBoolean());
            } finally {
                System.setErr(oldErr);
            }
            List<HintDescription> hints = new ArrayList<>();

            for (Entry<HintMetadata, ? extends Collection<? extends HintDescription>> e : allHints.entrySet()) {
                if (settings.isEnabled(e.getKey()) && e.getKey().kind == Hint.Kind.INSPECTION && !e.getKey().options.contains(HintMetadata.Options.NO_BATCH)) {
                    hints.addAll(e.getValue());
                }
            }
            final Map<String, String> id2DisplayName = Utils.computeId2DisplayName(hints);
            ClasspathInfo cpInfo = new ClasspathInfo.Builder(bootCP).setClassPath(compileCP).setSourcePath(sourceCP).setModuleBootPath(bootCP).build();

            JavaSource.create(cpInfo, sourceFiles.keySet()).runUserActionTask(new Task<CompilationController>() {

                @Override
                public void run(CompilationController parameter) throws Exception {
                    if (parameter.toPhase(JavaSource.Phase.RESOLVED).compareTo(JavaSource.Phase.RESOLVED) < 0) {
                        return;
                    }

                    List<ErrorDescription> eds = new HintsInvoker(settings, /*XXX*/new AtomicBoolean()).computeHints(parameter, hints);

                    if (eds != null) {
                        //TODO: sort errors!!!
                        for (ErrorDescription ed : eds) {
                            CompilationUnitTree originalUnit = sourceFiles.get(ed.getFile());
                            if (originalUnit == null) {
                                //XXX: log properly!!!
                                continue;
                            }
                            TreePath posPath = pathFor(originalUnit, trees.getSourcePositions(), ed.getRange().getBegin().getOffset());
                            String category = Utils.categoryName(ed.getId(), id2DisplayName);
                            Kind diagKind;
                            switch (ed.getSeverity()) {
                                case ERROR: diagKind = Kind.ERROR; break;
                                case VERIFIER:
                                case WARNING: diagKind = Kind.WARNING; break;
                                case HINT:
                                default: diagKind = Kind.NOTE; break;
                            }
                            trees.printMessage(diagKind, category + ed.getDescription(), posPath.getLeaf(), posPath.getCompilationUnit());
                        }
                    }
                }
            }, true);
        } catch (SecurityException | IllegalArgumentException | IllegalAccessException | NoSuchMethodException | InvocationTargetException | IOException ex) {
            processingEnv.getMessager().printMessage(Kind.ERROR, "Unexpected exception: " + ex.getMessage());
            Logger.getLogger(ProcessorImpl.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            TOP_LOGGER.setLevel(originalLoggerLevel);
            if (toDelete != null) {
                try {
                    Files.delete(toDelete);
                } catch (IOException ex) {
                    processingEnv.getMessager().printMessage(Kind.ERROR, "Unexpected exception: " + ex.getMessage());
                    Logger.getLogger(ProcessorImpl.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }