From 005a2411f034a51ae36c7fb96a917fb4258ea76f Mon Sep 17 00:00:00 2001
From: Ned Palacios <npdoesmc@gmail.com>
Date: Sat, 25 Nov 2023 23:28:37 +0800
Subject: [PATCH] feat: support for nonstaticmethodaccesserror.go

---
 .../java/non_static_method_access_error.go    | 62 ++++++++++++++++++-
 .../non_static_method_access_error/test.txt   | 20 +++---
 2 files changed, 69 insertions(+), 13 deletions(-)

diff --git a/error_templates/java/non_static_method_access_error.go b/error_templates/java/non_static_method_access_error.go
index 416b68a..214d82a 100644
--- a/error_templates/java/non_static_method_access_error.go
+++ b/error_templates/java/non_static_method_access_error.go
@@ -1,15 +1,71 @@
 package java
 
-import lib "github.com/nedpals/errgoengine"
+import (
+	"fmt"
+	"strings"
+
+	lib "github.com/nedpals/errgoengine"
+)
+
+type nonStaticMethodAccessErrorCtx struct {
+	class  string
+	method string
+	parent lib.SyntaxNode
+}
 
 var NonStaticMethodAccessError = lib.ErrorTemplate{
 	Name:              "NonStaticMethodAccessError",
 	Pattern:           comptimeErrorPattern(`non-static method (?P<method>\S+)\(\) cannot be referenced from a static context`),
 	StackTracePattern: comptimeStackTracePattern,
+	OnAnalyzeErrorFn: func(cd *lib.ContextData, m *lib.MainError) {
+		nCtx := nonStaticMethodAccessErrorCtx{parent: m.Nearest}
+
+		// Get the class name
+		symbols := cd.Symbols[cd.MainDocumentPath()]
+		for _, sym := range symbols.Symbols {
+			if sym.Kind() == lib.SymbolKindClass && m.Nearest.Location().IsWithin(sym.Location()) {
+				nCtx.class = sym.Name()
+				break
+			}
+		}
+
+		m.Context = nCtx
+
+		lib.QueryNode(m.Nearest, strings.NewReader("(method_invocation name: (identifier) @method arguments: (argument_list))"), func(ctx lib.QueryNodeCtx) bool {
+			match := ctx.Cursor.FilterPredicates(ctx.Match, []byte(m.Nearest.Doc.Contents))
+			for _, c := range match.Captures {
+				node := lib.WrapNode(m.Nearest.Doc, c.Node)
+				m.Nearest = node
+				nCtx.method = node.Text()
+				return false
+			}
+			return true
+		})
+	},
 	OnGenExplainFn: func(cd *lib.ContextData, gen *lib.ExplainGenerator) {
-		// return "TODO:"
+		gen.Add("This error occurs when trying to access a non-static method from a static context. In Java, a non-static method belongs to an instance of the class and needs an object to be called upon.")
 	},
 	OnGenBugFixFn: func(cd *lib.ContextData, gen *lib.BugFixGenerator) {
-		// TODO
+		ctx := cd.MainError.Context.(nonStaticMethodAccessErrorCtx)
+
+		gen.Add("Instantiate and call the method", func(s *lib.BugFixSuggestion) {
+			s.AddStep("Create an instance of the class to access the non-static method").
+				AddFix(lib.FixSuggestion{
+					NewText: fmt.Sprintf("%s obj = new %s();\n", ctx.class, ctx.class),
+					StartPosition: lib.Position{
+						Line:   ctx.parent.StartPosition().Line,
+						Column: ctx.parent.StartPosition().Column,
+					},
+					EndPosition: lib.Position{
+						Line:   ctx.parent.EndPosition().Line,
+						Column: 0,
+					},
+				}).
+				AddFix(lib.FixSuggestion{
+					NewText:       "obj.",
+					StartPosition: ctx.parent.StartPosition(),
+					EndPosition:   ctx.parent.StartPosition(),
+				})
+		})
 	},
 }
diff --git a/error_templates/java/test_files/non_static_method_access_error/test.txt b/error_templates/java/test_files/non_static_method_access_error/test.txt
index 660209b..2d22452 100644
--- a/error_templates/java/test_files/non_static_method_access_error/test.txt
+++ b/error_templates/java/test_files/non_static_method_access_error/test.txt
@@ -9,22 +9,22 @@ template: "Java.NonStaticMethodAccessError"
 ---
 # NonStaticMethodAccessError
 This error occurs when trying to access a non-static method from a static context. In Java, a non-static method belongs to an instance of the class and needs an object to be called upon.
-
 ```
         // Attempt to call the non-static method without creating an object
         printMessage(); // This will result in an error
         ^^^^^^^^^^^^
     }
 }
-
 ```
 ## Steps to fix
-1. **Create an instance of the class to access the non-static method**
-```java
-Main obj = new Main();
-obj.printMessage(); // This will properly call the non-static method
+### Instantiate and call the method
+Create an instance of the class to access the non-static method
+```diff
+    public static void main(String[] args) {
+        // Attempt to call the non-static method without creating an object
+-         printMessage(); // This will result in an error
++         Main obj = new Main();
++         obj.printMessage(); // This will result in an error
+    }
+}
 ```
-
-The issue arises because the `printMessage()` method is non-static, meaning it belongs to an instance of the class. To use this method within the `main` method, you must create an object of the `Main` class and then call the `printMessage()` method using that object.
-
-This correction instantiates an object (`obj`) of the `Main` class and then calls the `printMessage()` method using this object, resolving the error.