Support two-step method calls and allow retrieving built-in methods using getattr

Related: https://github.com/bazelbuild/starlark/issues/20#issuecomment-456647994, https://github.com/bazelbuild/bazel/issues/5224

It's now possible to call methods in two steps `y = x.f; y()`
Also, `getattr` can now be used to retrieve built-in methods.

Closes #8931.

PiperOrigin-RevId: 259711316
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java
index 43a17af..87ba491 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java
@@ -1446,11 +1446,7 @@
 
   @Test
   public void testStructAccessOfMethod() throws Exception {
-    new SkylarkTest()
-        .update("mock", new Mock())
-        .testIfExactError(
-            "object of type 'Mock' has no field 'function', however, a method of that name exists",
-            "v = mock.function");
+    new SkylarkTest().update("mock", new Mock()).testStatement("v = mock.function", null);
   }
 
   @Test
@@ -1894,15 +1890,16 @@
   public void testGetattrMethods() throws Exception {
     new SkylarkTest()
         .update("mock", new Mock())
-        .setUp("a = getattr(mock, 'struct_field', 'no')",
-            "b = getattr(mock, 'function', 'no')",
-            "c = getattr(mock, 'is_empty', 'no')",
-            "d = getattr('str', 'replace', 'no')",
-            "e = getattr(mock, 'other', 'no')\n")
+        .setUp(
+            "a = str(getattr(mock, 'struct_field', 'no'))",
+            "b = str(getattr(mock, 'function', 'no'))",
+            "c = str(getattr(mock, 'is_empty', 'no'))",
+            "d = str(getattr('str', 'replace', 'no'))",
+            "e = str(getattr(mock, 'other', 'no'))\n")
         .testLookup("a", "a")
-        .testLookup("b", "no")
-        .testLookup("c", "no")
-        .testLookup("d", "no")
+        .testLookup("b", "<built-in function function>")
+        .testLookup("c", "<built-in function is_empty>")
+        .testLookup("d", "<built-in function replace>")
         .testLookup("e", "no");
   }