From 6138121591a77b5888bd2706cdf361c18096e6cb Mon Sep 17 00:00:00 2001 From: Anton Banchev Date: Sat, 7 Mar 2026 21:10:01 +0100 Subject: [PATCH] feat: hide compiler-generated synthetic fields from autocomplete Filter out class$0, class$1, etc. fields that Java compilers generate for .class literal expressions when targeting pre-Java 5 bytecode. These are internal compiler implementation details that should not appear in completion results. Added configurable hideSyntheticFields property (default: true) on JavaLanguageSupport with getter/setter API, wired through to SourceCompletionProvider.isAccessible(). --- .../rsta/ac/java/JavaCompletionProvider.java | 10 +++++ .../rsta/ac/java/JavaLanguageSupport.java | 33 ++++++++++++++ .../ac/java/SourceCompletionProvider.java | 43 +++++++++++++++++++ 3 files changed, 86 insertions(+) diff --git a/RSTALanguageSupport/src/main/java/org/fife/rsta/ac/java/JavaCompletionProvider.java b/RSTALanguageSupport/src/main/java/org/fife/rsta/ac/java/JavaCompletionProvider.java index e7126c87..3ffd0787 100644 --- a/RSTALanguageSupport/src/main/java/org/fife/rsta/ac/java/JavaCompletionProvider.java +++ b/RSTALanguageSupport/src/main/java/org/fife/rsta/ac/java/JavaCompletionProvider.java @@ -123,6 +123,16 @@ public List getCompletionsAt(JTextComponent tc, Point p) { } + /** + * Returns the source completion provider used internally. + * + * @return The source completion provider. + */ + SourceCompletionProvider getSourceProvider() { + return sourceProvider; + } + + /** * Returns the jars on the "build path". * diff --git a/RSTALanguageSupport/src/main/java/org/fife/rsta/ac/java/JavaLanguageSupport.java b/RSTALanguageSupport/src/main/java/org/fife/rsta/ac/java/JavaLanguageSupport.java index e1a31b18..d662dd61 100644 --- a/RSTALanguageSupport/src/main/java/org/fife/rsta/ac/java/JavaLanguageSupport.java +++ b/RSTALanguageSupport/src/main/java/org/fife/rsta/ac/java/JavaLanguageSupport.java @@ -62,6 +62,11 @@ public class JavaLanguageSupport extends AbstractLanguageSupport { */ private JarManager jarManager; + /** + * Whether to hide compiler-generated synthetic fields from completions. + */ + private boolean hideSyntheticFields = true; + /** * Client property installed on text areas that points to a listener. */ @@ -109,6 +114,33 @@ public JarManager getJarManager() { } + /** + * Returns whether compiler-generated synthetic fields (e.g. + * {@code class$0}) are hidden from completion results. The default + * value is {@code true}. + * + * @return Whether synthetic fields are hidden. + * @see #setHideSyntheticFields(boolean) + */ + public boolean getHideSyntheticFields() { + return hideSyntheticFields; + } + + + /** + * Sets whether compiler-generated synthetic fields (e.g. {@code class$0}, + * {@code class$1}) should be hidden from completion results. These + * fields are generated by compilers for {@code .class} literal + * expressions when targeting pre-Java 5 bytecode. + * + * @param hide Whether to hide synthetic fields. + * @see #getHideSyntheticFields() + */ + public void setHideSyntheticFields(boolean hide) { + this.hideSyntheticFields = hide; + } + + /** * Returns the Java parser running on a text area with this Java language * support installed. @@ -134,6 +166,7 @@ public JavaParser getParser(RSyntaxTextArea textArea) { public void install(RSyntaxTextArea textArea) { JavaCompletionProvider p = new JavaCompletionProvider(jarManager); + p.getSourceProvider().setHideSyntheticFields(hideSyntheticFields); // Can't use createAutoCompletion(), as Java's is "special." AutoCompletion ac = new JavaAutoCompletion(p, textArea); ac.setListCellRenderer(new JavaCellRenderer()); diff --git a/RSTALanguageSupport/src/main/java/org/fife/rsta/ac/java/SourceCompletionProvider.java b/RSTALanguageSupport/src/main/java/org/fife/rsta/ac/java/SourceCompletionProvider.java index 51ff1102..d7cb99fa 100644 --- a/RSTALanguageSupport/src/main/java/org/fife/rsta/ac/java/SourceCompletionProvider.java +++ b/RSTALanguageSupport/src/main/java/org/fife/rsta/ac/java/SourceCompletionProvider.java @@ -89,6 +89,15 @@ class SourceCompletionProvider extends DefaultCompletionProvider { //Shorthand completions (templates and comments) private ShorthandCompletionCache shorthandCache; + + /** + * Whether to hide compiler-generated synthetic members (e.g. + * {@code class$0} fields, {@code access$0} methods) from completion + * results. These are generated by compilers for {@code .class} literal + * expressions and inner class private member access. Defaults to + * {@code true}. + */ + private boolean hideSyntheticFields = true; /** * Constructor. */ @@ -113,6 +122,30 @@ class SourceCompletionProvider extends DefaultCompletionProvider { } + /** + * Returns whether compiler-generated synthetic fields are hidden from + * completion results. + * + * @return Whether synthetic fields are hidden. + * @see #setHideSyntheticFields(boolean) + */ + boolean isHideSyntheticFields() { + return hideSyntheticFields; + } + + + /** + * Sets whether compiler-generated synthetic fields (e.g. {@code class$0}) + * should be hidden from completion results. + * + * @param hide Whether to hide synthetic fields. + * @see #isHideSyntheticFields() + */ + void setHideSyntheticFields(boolean hide) { + this.hideSyntheticFields = hide; + } + + private void addCompletionsForStaticMembers(Set set, CompilationUnit cu, ClassFile cf, String pkg) { @@ -614,6 +647,16 @@ public SourceLocation getSourceLocForClass(String className) { */ private boolean isAccessible(MemberInfo info, String pkg) { + // Filter compiler-generated synthetic members from completion results: + // - class$N fields: generated for .class literal expressions (pre-Java 5) + // - access$N methods: generated for inner class private member access + if (hideSyntheticFields) { + String name = info.getName(); + if (name != null && (name.startsWith("class$") || name.startsWith("access$"))) { + return false; + } + } + boolean accessible = false; int access = info.getAccessFlags();