diff --git a/.gitignore b/.gitignore
index 6fb050f33df6f21162c8152feb2c2b9d7e8bb16b..2454cbee83e0a4cfe59f360058c3e1901a113b69 100644
--- a/.gitignore
+++ b/.gitignore
@@ -150,4 +150,4 @@ Session.vim
 
 ### recolic
 *.gi
-
+*.log
diff --git a/src/main/java/chocopy/common/analysis/types/ClassValueType.java b/src/main/java/chocopy/common/analysis/types/ClassValueType.java
index 6e91683fd9c6780f1a82fc682e43cfc0f48de643..c84550314b5ddadd471f7fbac90979fccb050a23 100644
--- a/src/main/java/chocopy/common/analysis/types/ClassValueType.java
+++ b/src/main/java/chocopy/common/analysis/types/ClassValueType.java
@@ -1,9 +1,11 @@
 package chocopy.common.analysis.types;
 
+import java.util.Map;
 import java.util.Objects;
 
 import chocopy.common.astnodes.ClassType;
 import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
 /** Represents the semantic value of a simple class reference. */
@@ -12,6 +14,10 @@ public class ClassValueType extends ValueType {
     /** The name of the class. */
     private final String className;
 
+    // recolic;
+    @JsonIgnore
+    public Map<String, SymbolType> memberMap = null;
+
     /** A class type for the class named CLASSNAME. */
     @JsonCreator
     public ClassValueType(@JsonProperty String className) {
diff --git a/src/main/java/chocopy/common/astnodes/ClassDef.java b/src/main/java/chocopy/common/astnodes/ClassDef.java
index dad7e2a4abcb2653da7bf79053d824d682e84095..16884822ffddd850f5c1b0c5e5866d72b3055263 100644
--- a/src/main/java/chocopy/common/astnodes/ClassDef.java
+++ b/src/main/java/chocopy/common/astnodes/ClassDef.java
@@ -1,8 +1,10 @@
 package chocopy.common.astnodes;
 
+import java.util.Map;
 import java.util.List;
 
 import chocopy.common.analysis.NodeAnalyzer;
+import chocopy.common.analysis.types.SymbolType;
 import java_cup.runtime.ComplexSymbolFactory.Location;
 
 /** A class definition. */
@@ -15,6 +17,9 @@ public class ClassDef extends Declaration {
     /** Body of the class. */
     public final List<Declaration> declarations;
 
+    // Recolic:
+    public Map<String, SymbolType> memberMap = null;
+
     /** An AST for class
      *    NAME(SUPERCLASS):
      *       DECLARATIONS.
diff --git a/src/main/java/chocopy/pa2/DeclarationAnalyzer.java b/src/main/java/chocopy/pa2/DeclarationAnalyzer.java
index 12c534b6f08a582ae715628c2e1ac88fd3da3d15..09ab320be57e261ebe676d984ff232ce36379b9b 100644
--- a/src/main/java/chocopy/pa2/DeclarationAnalyzer.java
+++ b/src/main/java/chocopy/pa2/DeclarationAnalyzer.java
@@ -8,6 +8,10 @@ import chocopy.common.analysis.types.SymbolType;
 import chocopy.common.analysis.types.ValueType;
 import chocopy.common.astnodes.*;
 
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
 /**
  * Analyzes declarations to create a top-level symbol table.
  * Recolic: This class will ONLY fill the symTable. Every `Program` and `FuncDef` has a sym table.
@@ -60,7 +64,22 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<SymbolType> {
 
     @Override
     public SymbolType analyze(ClassDef classDef) {
-        System.out.println("debug: classdef");
+        assert classDef.memberMap == null;
+        classDef.memberMap = new HashMap<>();
+        assert classDef.memberMap != null;
+
+        ClassValueType result_type = new ClassValueType(classDef.name.name);
+        SymbolTable<SymbolType> symLayer = new SymbolTable<>(sym);
+        symLayer.put("self", result_type);
+        sym = symLayer;
+
+        for(Declaration decl : classDef.declarations) {
+            String name = decl.getIdentifier().name;
+            SymbolType type = decl.dispatch(this);
+            classDef.memberMap.put(name, type);
+        }
+
+        sym = sym.getParent();
         return new ClassValueType(classDef.name.name);
     }
 
@@ -72,9 +91,12 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<SymbolType> {
         assert funcDef.symTable != null; // may suck if partial-compiling happens...
 
         // Func parameter list
+        List<ValueType> args = new ArrayList<>();
         for(TypedVar param : funcDef.params) {
             String name = param.identifier.name;
-            sym.put(name, analyze(param));
+            ValueType type = ValueType.annotationToValueType(param.type);
+            sym.put(name, type);
+            args.add(type);
         }
 
         for(Declaration decl : funcDef.declarations) {
@@ -87,7 +109,8 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<SymbolType> {
         sym = sym.getParent();
         if(sym == null)
             throw new RuntimeException("logic error: sym parent is null while returning..");
-        return new FuncType(ValueType.annotationToValueType(funcDef.returnType));
+        FuncType funcT = new FuncType(args, ValueType.annotationToValueType(funcDef.returnType));
+        return funcT;
     }
 
     @Override
diff --git a/src/main/java/chocopy/pa2/TypeChecker.java b/src/main/java/chocopy/pa2/TypeChecker.java
index 5b4e4903047ba8215de5f357fc04b760217532f0..08faeb74a2afd82f5481e3da57ef4ac6222b5465 100644
--- a/src/main/java/chocopy/pa2/TypeChecker.java
+++ b/src/main/java/chocopy/pa2/TypeChecker.java
@@ -2,10 +2,7 @@ package chocopy.pa2;
 
 import chocopy.common.analysis.AbstractNodeAnalyzer;
 import chocopy.common.analysis.SymbolTable;
-import chocopy.common.analysis.types.FuncType;
-import chocopy.common.analysis.types.ListValueType;
-import chocopy.common.analysis.types.SymbolType;
-import chocopy.common.analysis.types.ValueType;
+import chocopy.common.analysis.types.*;
 import chocopy.common.astnodes.*;
 
 import java.util.*;
@@ -247,6 +244,21 @@ public class TypeChecker extends AbstractNodeAnalyzer<SymbolType> {
         }
     }
 
+    @Override
+    public SymbolType analyze(MemberExpr node) {
+        ClassValueType objType = (ClassValueType) node.object.dispatch(this);
+        if(objType == null) {
+            err(node, ". operator left operand is not object type.");
+            return NONE_TYPE;
+        }
+        SymbolType resultType = objType.memberMap.get(node.member.name); // currently won't work. classDef not analyzed.
+        if(resultType == null) {
+            err(node, "undefined identifier " + node.member.name + " as object member.");
+            return NONE_TYPE;
+        }
+        return resultType;
+    }
+
     @Override
     public SymbolType analyze(Identifier id) {
         String varName = id.name;