sclass LoadableUtilsHelper { transient settable S exampleProgramID = #1031393; transient settable S loadableUtilsSnippetID = #1030952; transient settable S includeSnippetID = #1030953; transient settable S globalSnippetID = #1020737; transient settable bool onlyImportDefined = true; // for classes and functions transient settable IPred dontDelegatePredicate = name -> false; transient S transpilerOutput; transient Set requestedFunctions, requestedClasses; transient Set have, haveClasses; transient new Set blockedFunctions; transient new Set blockedClasses; transient Set newFunctions, newClasses; transient new Set imported; transient Set importedClasses; transient Set toImport, classesToImport; transient new SS modifiers; selfType transpilerOutput(S transpilerOutput) { this.transpilerOutput = transpilerOutput; this; } S getTranspilerOutput() { new RunTranspiler rt; rt.onPreparingTranspiler(transpiler -> setOpt(transpiler, printMapLikes := true)); ret transpilerOutput = hijackPrint(-> rt.get(loadSnippet(exampleProgramID))); } void prepare { if (transpilerOutput == null) getTranspilerOutput(); LS transpilerLines = mapLines(transpilerOutput, s -> dropLeadingAngleBracketStuff(s)); requestedFunctions = asSet(startingWithIC_dropAndTrim("Compiling function:", transpilerLines); requestedClasses = asSet(startingWithIC_dropAndTrim("Compiling class:", transpilerLines); print(n2(requestedFunctions, "requested function")); print(n2(requestedClasses, "requested class", "requested classes")); for (PairS p : parseColonPropertyPairs(lines(transpilerLines))) if (functionAdjuvantKeywords().contains(p.a)) modifiers.put(p.b, p.a); print(n2(modifiers, "function modifier")); S text = loadSnippet(loadableUtilsSnippetID); have = asSet(lmap tok_lastIdentifier(jextractAll("please include function .", text))); haveClasses = asSet(lmap tok_lastIdentifier(jextractAll("please include class .", text))); print("Have " + n2(have, "function")); S includeSnippet = joinNemptiesWithEmptyLines( loadSnippet(includeSnippetID), loadSnippet(globalSnippetID)); new Matches m; for (S comment : trimAll(getJavaLineComments(text))) { if (find3("don't include function *", comment, m)) blockedFunctions.add($1); if (find3("don't include class *", comment, m)) blockedClasses.add($1); } for (S comment : trimAll(getJavaLineComments(includeSnippet))) if (swic(comment, "don't import ")) blockedFunctions.add(tok_lastIdentifier(comment)); for (S s : jextractAll(javaTok(includeSnippet), "please include function .")) blockedFunctions.add(tok_lastIdentifier(s)); print(n2(blockedFunctions, "blocked function") + ": " + blockedFunctions); print(n2(blockedClasses, "blocked class", "blocked classes") + ": " + blockedClasses); Set shouldHave = setMinusSet(requestedFunctions, blockedFunctions); newFunctions = setMinusSet(shouldHave, have); newFunctions = antiFilterToSet(dontDelegatePredicate, newFunctions); print(n2(newFunctions, "new function")); Set shouldHaveClasses = setMinusSet(requestedClasses, blockedClasses); newClasses = setMinusSet(shouldHaveClasses, haveClasses); newClasses = antiFilterToSet(dontDelegatePredicate, newClasses); print(n2(newClasses, "new class", "new classes")); for (S s : tlft(includeSnippet)) { s = simpleSpaces(s); if (startsWith(s, "import static ")) imported.add(tok_lastIdentifier(s)); } print(n2(imported, "imported function")); importedClasses = asSet(lmap tok_lastIdentifier(jextractAll("import loadableUtils.utils.;", includeSnippet))); print(n2(importedClasses, "imported class", "imported classes")); toImport = toTreeSet(setMinusSet(onlyImportDefined ? have : shouldHave, imported)); toImport = antiFilterToSet(dontDelegatePredicate, toImport); toImport = setMinusSet(toImport, blockedFunctions); print(n2(toImport) + " function(s) to import"); classesToImport = toTreeSet(setMinusSet(onlyImportDefined ? haveClasses : shouldHaveClasses, importedClasses)); print(n2(classesToImport) + " class(es) to import"); } LPairS suggestedAppends() { ret ll(pair(loadableUtilsSnippetID, mapToLines(newFunctions, f -> "please include function " + f + ".") + mapToLines(newClasses, c -> "please include class " + c + ".")), pair(includeSnippetID, mapToLines(toImport, f -> "import static loadableUtils.utils." + appendSpaceIfNempty(modifiers.get(f)) + f + ";") + mapToLines(classesToImport, c -> "import loadableUtils.utils." + c + ";") ) ); } }