From 7ea527abd82993e52626207f5713b5817be53872 Mon Sep 17 00:00:00 2001
From: Nicholas Robinson <nwrobins@edu.uwaterloo.ca>
Date: Fri, 6 Mar 2020 21:34:56 -0500
Subject: [PATCH] check protected

---
 NameNode.py | 35 ++++++++++++++++++++++++++++++++---
 1 file changed, 32 insertions(+), 3 deletions(-)

diff --git a/NameNode.py b/NameNode.py
index 3401352..66c5125 100644
--- a/NameNode.py
+++ b/NameNode.py
@@ -1,5 +1,5 @@
 from AST import ASTNode, getParseTreeNodes
-from TheTypeNode import TypeStruct
+from TheTypeNode import TypeStruct, getSupers
 import MemberNodes
 import TypeNodes
 from Environment import Env
@@ -127,7 +127,22 @@ class NameNode(ASTNode):
 
                     self.prefix = currPrefix + "." + staticFieldName
                     self.IDs = self.IDs[index+2:]
+
+                    # if protected, check if we have access to it
+                    if "protected" in typeFieldNode.mods:
+
+                        # get typeFieldNode's class it was declared in
+                        typeFieldNodeClass = typeFieldNode.env.getNode(typeFieldNode.typeName, "type").canonName
+
+                        # get current class we're in
+                        curClass = self.env.getNode(self.typeName, "type")
+
+                        # check to see if typeFieldNode's class is in the current class' super list
+                        if typeFieldNodeClass != curClass.canonName and typeFieldNodeClass not in getSupers(curClass):
+                            raise Exception("ERROR: Class {} is attempting to access a protected field from class {}".format(curClass.canonName, typeFieldNodeClass))
+
                     return True
+
                 return False
             elif self.methodInvoke and index+1 == len(self.IDs) - 1:
                 # TODO set the most recent? is this the correct implementation we want?
@@ -196,8 +211,22 @@ class NameNode(ASTNode):
                     curType = curType.env.getNode(self.IDs[0], 'fieldDcl')
 
                 # at this stage, all newly resolved field should be non static:
-                if curType.__class__.__name__ == 'FieldNode' and 'static' in curType.mods:
-                    raise Exception("ERROR: Non-static access of static field {}".format(curType.name))
+                if curType.__class__.__name__ == 'FieldNode':
+                    if 'static' in curType.mods:
+                        raise Exception("ERROR: Non-static access of static field {}".format(curType.name))
+
+                    # if protected, check if we have access to it
+                    if "protected" in curType.mods:
+
+                        # get curType's class it was declared in
+                        typeFieldNodeClass = curType.env.getNode(curType.typeName, "type").canonName
+
+                        # get current class we're in
+                        curClass = self.env.getNode(self.typeName, "type")
+
+                        # check to see if curType's class is in the current class' super list
+                        if typeFieldNodeClass != curClass.canonName and typeFieldNodeClass not in getSupers(curClass):
+                            raise Exception("ERROR: Class {} is attempting to access a protected field from class {}".format(curClass.canonName, typeFieldNodeClass))
 
                 self.prefix = self.prefix + "." + self.IDs[0]
                 self.IDs.pop(0)
-- 
GitLab