This is an automated email from the ASF dual-hosted git repository.

jdaugherty pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/grails-intellij-plugin.git


The following commit(s) were added to refs/heads/main by this push:
     new 1e4be3c  Complete static domain members for class-reference qualifiers 
on 2026.2
1e4be3c is described below

commit 1e4be3cfcf6e8c4b39ace81c8787d7a19fd96beb
Author: James Daugherty <[email protected]>
AuthorDate: Sun Jul 19 10:13:51 2026 -0400

    Complete static domain members for class-reference qualifiers on 2026.2
    
    Since IntelliJ 2026.2 a bare class-reference qualifier (Domain.<caret>) is 
treated as
    an instance type during code completion, so the platform filters 
static-only members
    out of the variants even though the members contributor still produces 
them. Static
    domain methods (createCriteria, list, get, listOrderBy<Prop>, ...) 
therefore stopped
    appearing in completion.
    
    Add DomainStaticMemberCompletionProvider, which recovers the domain class 
from the
    static qualifier reference and contributes these members explicitly via a 
new
    DomainMembersProvider.processStaticMembersForCompletion() helper. Fixes 
DomainClassMethodsCompletionTest.
---
 .../grails/GrailsCompletionContributor.java        |  2 +
 .../references/domain/DomainMembersProvider.java   | 15 ++++
 .../DomainStaticMemberCompletionProvider.java      | 85 ++++++++++++++++++++++
 3 files changed, 102 insertions(+)

diff --git a/src/org/jetbrains/plugins/grails/GrailsCompletionContributor.java 
b/src/org/jetbrains/plugins/grails/GrailsCompletionContributor.java
index 1f2f99e..92816d6 100644
--- a/src/org/jetbrains/plugins/grails/GrailsCompletionContributor.java
+++ b/src/org/jetbrains/plugins/grails/GrailsCompletionContributor.java
@@ -30,6 +30,7 @@ import com.intellij.psi.PsiModifier;
 import com.intellij.util.ProcessingContext;
 import org.jetbrains.annotations.NotNull;
 import 
org.jetbrains.plugins.grails.lang.gsp.psi.groovy.api.GrGspDeclarationHolder;
+import 
org.jetbrains.plugins.grails.references.domain.DomainStaticMemberCompletionProvider;
 import 
org.jetbrains.plugins.grails.references.domain.GormDynamicFinderCompletionProvider;
 import 
org.jetbrains.plugins.grails.references.domain.GormFetchModeCompletionProvider;
 import org.jetbrains.plugins.groovy.lang.completion.GroovyCompletionData;
@@ -67,6 +68,7 @@ public final class GrailsCompletionContributor extends 
CompletionContributor {
 
   public GrailsCompletionContributor() {
     extend(CompletionType.BASIC, grReferencePattern, new 
GormDynamicFinderCompletionProvider());
+    extend(CompletionType.BASIC, grReferencePattern, new 
DomainStaticMemberCompletionProvider());
 
     extend(CompletionType.BASIC, 
PlatformPatterns.psiElement(GroovyTokenTypes.mIDENT).withParent(
       PsiJavaPatterns.psiField().withModifiers(PsiModifier.STATIC)), new 
GrailsStaticFieldCompletionProvider(true));
diff --git 
a/src/org/jetbrains/plugins/grails/references/domain/DomainMembersProvider.java 
b/src/org/jetbrains/plugins/grails/references/domain/DomainMembersProvider.java
index 411620c..22ea469 100644
--- 
a/src/org/jetbrains/plugins/grails/references/domain/DomainMembersProvider.java
+++ 
b/src/org/jetbrains/plugins/grails/references/domain/DomainMembersProvider.java
@@ -145,6 +145,21 @@ public class DomainMembersProvider extends MemberProvider {
     return true;
   }
 
+  /**
+   * Enumerates the static domain members ({@code createCriteria}, {@code 
list}, {@code get},
+   * {@code listOrderBy...} etc.) available on a domain-class reference. Used 
by code completion:
+   * since 2026.2 the platform treats a bare class-reference qualifier as an 
instance type and
+   * filters these static-only members out of the completion variants, so 
completion must contribute
+   * them explicitly.
+   */
+  public static void processStaticMembersForCompletion(@NotNull 
GrReferenceExpression refExpr,
+                                                       @NotNull PsiClass 
domainClass,
+                                                       @NotNull 
PsiScopeProcessor processor) {
+    DomainDescriptor descriptor = DomainDescriptor.getDescriptor(domainClass);
+    descriptor.processStaticMethods(processor, null, ResolveState.initial());
+    testForStaticFinderMethod(refExpr, descriptor, processor);
+  }
+
   private static boolean testForStaticFinderMethod(GrReferenceExpression 
refExpr,
                                                    DomainDescriptor descriptor,
                                                    PsiScopeProcessor 
processor) {
diff --git 
a/src/org/jetbrains/plugins/grails/references/domain/DomainStaticMemberCompletionProvider.java
 
b/src/org/jetbrains/plugins/grails/references/domain/DomainStaticMemberCompletionProvider.java
new file mode 100644
index 0000000..b5d8341
--- /dev/null
+++ 
b/src/org/jetbrains/plugins/grails/references/domain/DomainStaticMemberCompletionProvider.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2000-2026 JetBrains s.r.o. and contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.plugins.grails.references.domain;
+
+import com.intellij.codeInsight.completion.CompletionParameters;
+import com.intellij.codeInsight.completion.CompletionProvider;
+import com.intellij.codeInsight.completion.CompletionResultSet;
+import com.intellij.openapi.util.Key;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiReference;
+import com.intellij.psi.ResolveState;
+import com.intellij.psi.scope.PsiScopeProcessor;
+import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.groovy.lang.completion.GroovyCompletionUtil;
+import 
org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
+import 
org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Contributes the static domain members (e.g. {@code createCriteria}, {@code 
list},
+ * {@code listOrderBy...}) for a static domain-class reference like {@code 
Domain.<caret>}.
+ *
+ * <p>Since IntelliJ 2026.2 a bare class-reference qualifier is treated as an 
instance type during
+ * code completion, so the platform filters these static-only members out of 
the variants even
+ * though the members contributor still produces them. Contribute them 
explicitly here, recovering
+ * the domain class from the static qualifier reference (like {@link 
GormDynamicFinderCompletionProvider}).</p>
+ */
+public final class DomainStaticMemberCompletionProvider extends 
CompletionProvider<CompletionParameters> {
+
+  @Override
+  protected void addCompletions(@NotNull CompletionParameters parameters,
+                                @NotNull ProcessingContext context,
+                                @NotNull CompletionResultSet result) {
+    PsiElement parent = parameters.getPosition().getParent();
+    if (!(parent instanceof GrReferenceExpression refExpr)) return;
+
+    GrExpression qualifier = refExpr.getQualifierExpression();
+    if (qualifier == null) return;
+
+    PsiReference qualifierRef = qualifier.getReference();
+    PsiElement resolved = qualifierRef == null ? null : qualifierRef.resolve();
+    if (!(resolved instanceof PsiClass domainClass)) return;
+    if (!GormUtils.isGormBean(domainClass)) return;
+
+    List<PsiMethod> collected = new ArrayList<>();
+    PsiScopeProcessor processor = new PsiScopeProcessor() {
+      @Override
+      public boolean execute(@NotNull PsiElement element, @NotNull 
ResolveState state) {
+        if (element instanceof PsiMethod method) collected.add(method);
+        return true;
+      }
+
+      @Override
+      public <T> @Nullable T getHint(@NotNull Key<T> hintKey) {
+        return null; // no NameHint: enumerate every static member
+      }
+    };
+
+    DomainMembersProvider.processStaticMembersForCompletion(refExpr, 
domainClass, processor);
+
+    for (PsiMethod method : collected) {
+      result.addElement(GroovyCompletionUtil.createLookupElement(method));
+    }
+  }
+}

Reply via email to