Add 'did you mean' suggestion when accessing a struct field

--
PiperOrigin-RevId: 143380643
MOS_MIGRATED_REVID=143380643
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/DotExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/DotExpression.java
index 5d94498..ec5a8a8 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/DotExpression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/DotExpression.java
@@ -20,6 +20,7 @@
 import com.google.devtools.build.lib.syntax.compiler.ByteCodeUtils;
 import com.google.devtools.build.lib.syntax.compiler.DebugInfo;
 import com.google.devtools.build.lib.syntax.compiler.VariableScope;
+import com.google.devtools.build.lib.util.SpellChecker;
 import java.util.ArrayList;
 import java.util.List;
 import net.bytebuddy.implementation.bytecode.ByteCodeAppender;
@@ -64,19 +65,22 @@
    */
   public static Object checkResult(Object objValue, Object result, String name, Location loc)
       throws EvalException {
-    if (result == null) {
-      if (objValue instanceof ClassObject) {
-        String customErrorMessage = ((ClassObject) objValue).errorMessage(name);
-        if (customErrorMessage != null) {
-          throw new EvalException(loc, customErrorMessage);
-        }
-      }
-      throw new EvalException(
-          loc,
-          Printer.format(
-              "object of type '%s' has no field %r", EvalUtils.getDataTypeName(objValue), name));
+    if (result != null) {
+      return result;
     }
-    return result;
+    String suffix = "";
+    if (objValue instanceof ClassObject) {
+      String customErrorMessage = ((ClassObject) objValue).errorMessage(name);
+      if (customErrorMessage != null) {
+        throw new EvalException(loc, customErrorMessage);
+      }
+      suffix = SpellChecker.didYouMean(name, ((ClassObject) objValue).getKeys());
+    }
+    throw new EvalException(
+        loc,
+        String.format(
+            "object of type '%s' has no field '%s'%s",
+            EvalUtils.getDataTypeName(objValue), name, suffix));
   }
 
   /**
@@ -102,9 +106,10 @@
       }
     }
 
-    Iterable<MethodDescriptor> methods = objValue instanceof Class<?>
-        ? FuncallExpression.getMethods((Class<?>) objValue, name, loc)
-        : FuncallExpression.getMethods(objValue.getClass(), name, loc);
+    Iterable<MethodDescriptor> methods =
+        objValue instanceof Class<?>
+            ? FuncallExpression.getMethods((Class<?>) objValue, name)
+            : FuncallExpression.getMethods(objValue.getClass(), name);
 
     if (methods != null) {
       methods =