diff --git a/java/kotlin-extractor/src/main/java/com/semmle/extractor/java/OdasaOutput.java b/java/kotlin-extractor/src/main/java/com/semmle/extractor/java/OdasaOutput.java index a02d5dbc992..fd671b73884 100644 --- a/java/kotlin-extractor/src/main/java/com/semmle/extractor/java/OdasaOutput.java +++ b/java/kotlin-extractor/src/main/java/com/semmle/extractor/java/OdasaOutput.java @@ -269,7 +269,7 @@ public class OdasaOutput { * Any unique suffix needed to distinguish `sym` from other declarations with the same name. * For functions for example, this means its parameter signature. */ - private TrapFileManager getMembersWriterForDecl(File trap, IrDeclaration sym, String signature) { + private TrapFileManager getMembersWriterForDecl(File trap, File trapFileBase, TrapClassVersion trapFileVersion, IrDeclaration sym, String signature) { if (use_trap_locking) { TrapClassVersion currVersion = TrapClassVersion.fromSymbol(sym, log); String shortName = sym instanceof IrDeclarationWithName ? ((IrDeclarationWithName)sym).getName().asString() : "(name unknown)"; @@ -298,11 +298,30 @@ public class OdasaOutput { // then renamed to its trap-old name, then we // don't need to rewrite it only to rename it // again. - File trapOld = new File(trap.getParentFile(), trap.getName().replace(".trap.gz", ".trap-old.gz")); + File trapFileDir = trap.getParentFile(); + File trapOld = new File(trapFileDir, trap.getName().replace(".trap.gz", ".trap-old.gz")); if (trapOld.exists()) { log.warn("Not rewriting trap file for " + trap.toString() + " as the trap-old exists"); return null; } + // Otherwise, if any newer TRAP file has already + // been written then we don't need to write + // anything. + if (trapFileBase != null && trapFileVersion != null && trapFileDir.exists()) { + String trapFileBaseName = trapFileBase.getName(); + + for (File f: FileUtil.list(trapFileDir)) { + String name = f.getName(); + Matcher m = selectClassVersionComponents.matcher(name); + if (m.matches() && m.group(1).equals(trapFileBaseName)) { + TrapClassVersion v = new TrapClassVersion(Integer.valueOf(m.group(2)), Integer.valueOf(m.group(3)), Long.valueOf(m.group(4)), m.group(5)); + if (v.newerThan(trapFileVersion)) { + log.warn("Not rewriting trap file for " + trap.toString() + " as " + f.toString() + " exists"); + return null; + } + } + } + } } return trapWriter(trap, sym, signature); } @@ -390,6 +409,8 @@ public class OdasaOutput { * Trap file locking. */ + private final Pattern selectClassVersionComponents = Pattern.compile("(.*)#(-?[0-9]+)\\.(-?[0-9]+)-(-?[0-9]+)-(.*)\\.trap\\.gz"); + /** * CAUTION: to avoid the potential for deadlock between multiple concurrent extractor processes, * only one source file {@link TrapLocker} may be open at any time, and the lock must be obtained @@ -485,14 +506,12 @@ public class OdasaOutput { if (use_trap_locking) { lockTrapFile(trapFile); } - return getMembersWriterForDecl(trapFile, sym, signature); + return getMembersWriterForDecl(trapFile, trapFileBase, trapFileVersion, sym, signature); } else { return null; } } - private final Pattern selectClassVersionComponents = Pattern.compile("(.*)#(-?[0-9]+)\\.(-?[0-9]+)-(-?[0-9]+)-(.*)\\.trap\\.gz"); - @Override public void close() { if (trapFile!=null) {