/** * Collect and return the code coverage reports for all the raw functions. * * @param resume The continuation to pass the return value to. */ public static void codeCoverageReportsThen(final Continuation1<List<CodeCoverageReport>> resume) { AvailRuntime.current() .whenLevelOneSafeDo( new AvailTask(FiberDescriptor.commandPriority) { @Override public void value() { final List<CodeCoverageReport> reports = new ArrayList<>(activeRawFunctions.size()); // Loop over each instance, creating its report object. for (final A_RawFunction function : activeRawFunctions) { final A_Module module = function.module(); if (!module.equalsNil()) { final CodeCoverageReport report = new CodeCoverageReport( getInvocationStatistic((AvailObject) function).hasRun, function.startingChunk() != L2Chunk.unoptimizedChunk(), function.startingLineNumber(), module.moduleName().asNativeString(), function.methodName().asNativeString()); if (!reports.contains(report)) { reports.add(report); } } } AvailRuntime.current() .whenLevelOneUnsafeDo( new AvailTask(FiberDescriptor.commandPriority) { @Override public void value() { resume.value(reports); } }); } }); }
/** * Reset the code coverage details of all {@link CompiledCodeDescriptor raw functions} by * discarding their L2 optimized chunks and clearing their flags. When complete, resume the * supplied {@link Continuation0 continuation}. * * @param resume The {@link Continuation0 continuation to be executed upon completion}. */ @AvailMethod public static void ResetCodeCoverageDetailsThen(final Continuation0 resume) { AvailRuntime.current() .whenLevelOneSafeDo( new AvailTask(FiberDescriptor.commandPriority) { @Override public void value() { L2Chunk.invalidationLock.lock(); try { // Loop over each instance, setting the touched flag to // false and discarding optimizations. for (final A_RawFunction function : activeRawFunctions) { final AvailObject object = (AvailObject) function; getInvocationStatistic(object).hasRun = false; if (!function.module().equalsNil()) { object.startingChunk().invalidate(); } } AvailRuntime.current() .whenLevelOneUnsafeDo( new AvailTask(FiberDescriptor.commandPriority) { @Override public void value() { resume.value(); } }); } finally { L2Chunk.invalidationLock.unlock(); } } }); }
/** * (Re)generate the target {@linkplain Properties properties} file. * * @throws IOException If an exceptional situation arises while reading properties. */ public void generate() throws IOException { // Force correct initialization order... sigh. AvailRuntime.nextHash(); final File fileName = new File( String.format( "src/%s_%s.properties", baseName.replace('.', '/'), locale.getLanguage())); System.out.println(fileName.getAbsolutePath()); final String[] components = baseName.split("\\."); final File tempFileName = new File( String.format( "%s/%s_%s.propertiesTEMP", System.getProperty("java.io.tmpdir"), components[components.length - 1], locale.getLanguage())); assert fileName.getPath().endsWith(".properties"); final Properties properties = new Properties(); try (final FileInputStream inputStream = new FileInputStream(fileName)) { try (final InputStreamReader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8)) { properties.load(reader); } } catch (final FileNotFoundException e) { // Ignore. It's okay if the file doesn't already exist. } final PrintWriter writer = new PrintWriter(tempFileName, "UTF-8"); generatePreamble(writer); generateProperties(properties, writer); writer.close(); // Now switch the new file in. In the rare event of failure between // these steps, the complete content will still be available in the // corresponding *.propertiesTEMP file. boolean worked = fileName.delete(); if (!worked) { System.err.println( String.format("deleting the original properties file failed: %s", fileName)); } worked = tempFileName.renameTo(fileName); if (!worked) { throw new RuntimeException( String.format( "moving the temporary properties file failed: %s -> %s", tempFileName, fileName)); } }