JavadocComment
s) instead of the Strings representing the comment/nodes...the reference wont GC because of the way JP has bidirectional references... (in JavadocComment
s case, a reference to the Node it is commenting) If you have a reference to ANY node within the AST in JavaParser (i.e. even the smallest IntegerLiteralExpr
) it has a reference to it's parent, and so on and so forth. if the Javadoc comment never goes out of scope, you'll keep the whole thing in memory
i.e.
package a.b.c;
public class C{
/** I am a javadoc comment*/
int i = 2;
}
...if I read in the above Java class... and ONLY extract /use the JavadocComment
instance /* I am a javadoc comment /
this comment has a pointer reference to it's commented entity:
(in Comment base class)
@InternalProperty
private Node commentedNode;
and that Node (a FieldDeclaration
int i=2;
) will have a reference to it's parent : ClassOrInterfaceDeclaration
and that node will have a reference to it's parent, the CompilationUnit
public static final boolean keepNativeAPIReference = false;
Method (MethodDeclaration md)
{
NodeList<Modifier> ml = md.getModifiers();
NodeList<Parameter> pl = md.getParameters();
NodeList<ReferenceType> te = md.getThrownExceptions();
this.nativeJP_API_reference = keepNativeAPIReference ? md : null;
this.name = md.getNameAsString();
this.signature = md.getDeclarationAsString();
this.returnType = md.getType().toString();
this.returnFullType = keepNativeAPIReference ? md.getType() : null;
this.body // = md.getBody().isPresent() ? md.getBody().get().toString() : null; // In ConstructorDeclaration, this is an Optional<BlockStmt>, not here!
// = md.getBody().isPresent()
// ? SourceFile.prettyPrinter.print(md.getBody().get().toString())
// : null;
= md.getBody().isPresent()
? com.github.javaparser.printer.lexicalpreservation.LexicalPreservingPrinter.print(
com.github.javaparser.printer.lexicalpreservation.LexicalPreservingPrinter.setup(md.getBody().get()))
: null;
this.modifiers = new String[ml.size()];
this.parameterNames = new String[pl.size()];
this.parameterTypes = new String[pl.size()];
this.parameterFullTypes = keepNativeAPIReference ? new com.github.javaparser.ast.type.Type[pl.size()] : null;
this.exceptions = new String[te.size()];
this.jdComment = md.hasJavaDocComment() ? md.getJavadocComment().get().toString() : null;
int i = 0;
for (Parameter p : pl)
{
parameterNames[i] = p.getName().toString();
parameterTypes[i] = p.getType().toString();
// This will eat up more memory on the heap, and is completely unnecessary for the Java-Doc Tool to run.
// However, a user might wish to make use of this, so it is left to the public-boolean "keepNativeAPIReference"
if (keepNativeAPIReference) parameterFullTypes[i] = p.getType();
i++;
}
i = 0;
for (Modifier m : ml) modifiers[i++] = m.toString();
i = 0;
for (ReferenceType r : te) exceptions[i++] = r.toString();
}
this.body = md.getBody().isPresent()
? com.github.javaparser.printer.lexicalpreservation.LexicalPreservingPrinter.print(
com.github.javaparser.printer.lexicalpreservation.LexicalPreservingPrinter.setup(md.getBody().get()))
: null;
// This line is used to transmit it to "http://HiLite.me" and provide HTML-ified HiLited Java-Source Code.
// Afterwards, that HTML is inserted into each and every Method-Details Section of each and every Class, Inteface & Enumerated-Type
// Of a Java-Doc Page. This part works, but like I said, this is creating a lot of extra-memory use on the heap
// It's not a "MAJOR PROBLEM" .. but it does "SLOW THE JRE DOWN" eventually...
Node
s. They are the exact sequence of low level syntactic text pieces that form the source code, including whitespace, comments, everything. So if you take the tokens that form the method declaration and print them in sequence, you get the source code back.
Runtime.gc()
is invoked, as the heap grows - if the GC fails to clean the heap, the GC gets slower and slower and slower...
I think the issue here is that :
JavaParser runs at "source time" with input as a String (representing .java source code)
Spring operates as an annotation processor at Runtime (mostly) and by this time we are talking in Java bytecode
(Thats why Spring uses tools like ASM to manipulate the bytecode)
https://www.baeldung.com/java-asm
In short you have two separate "lifecycles" operating on separate "code formats"
(Strings/Tokens/Nodes... for JavaParser during source-time...i.e. like manipulating code in your IDE)
(Bytecodes...for Spring & ASM... doing bytecode manipulation at runtime during startup/annotation processing)
So the changes made to the bytecode by Spring (or the runtime objects/instances) will be operating on runtime bytecode and not the source Strings
StaticJavaParser
(because I parse around 500 Java Source Code Files in my build - for making better code-documentation that now has "Inline Code Hiliting" - and it helps to 'take out the trash' after I am done with a file...).
java.util.*
library? I need access to a field named modCount
in the AbstractList
or the AbstractCollection
class, so I can implement my Iterators better, and throw an exception that I really want to be able to throw, but cannot because I cannot access the field in the standard JDK implementation of these generics... Anybody know? Is it possible at Run-Time to insert a getter into standard-JDK class AbstractLust for protected field modCount, in "real-time" or "at run time" ??? I guarantee you that it's a bonafide bug in the JDK not to allow some kind of accessor method for this field... I need to be able to throw something known as "ConcurrentModificationException" in the specialized Iterators that I have written... But I cannot properly check for the Situations without access to the field - unless I horribly inefficient version of "the checker" ... Let me know...
I would want to "Insert" this getter method into a the JDK Class AbstractList
public int getModeCount() { return modCount; }
// So that I would be able to check in my "Iterators"
{
if (getModCount() != expectedModCount) throw new
ConcurrentModificationException("Underlying Vector Modified outside of ListIterator, this is not allowed.");
...
// Rest of Iterator Code
}
I would have to do this to the "Java JDK Byte Code for AbstractList" after the class had been loaded into memory by the ClassLoader. I cannot re-implement my own inherited version of AbstractList and simply add this method, because it is of much higher priority to allow programmer to reuse class java.util.Vector<E>
and never force them to use my own "proprietary" Collections or List. That's half the value of the package. Is this possible?