diff --git a/java-type-checker/.idea/misc.xml b/java-type-checker/.idea/misc.xml
index c24fcb0..a7ce7ea 100644
--- a/java-type-checker/.idea/misc.xml
+++ b/java-type-checker/.idea/misc.xml
@@ -12,5 +12,5 @@
-
+
\ No newline at end of file
diff --git a/java-type-checker/.idea/type-checker.iml b/java-type-checker/.idea/type-checker.iml
index 52e75c6..abd342a 100644
--- a/java-type-checker/.idea/type-checker.iml
+++ b/java-type-checker/.idea/type-checker.iml
@@ -2,7 +2,7 @@
-
+
diff --git a/java-type-checker/java_type_checker/expressions.py b/java-type-checker/java_type_checker/expressions.py
index 27ed57e..9a494e7 100644
--- a/java-type-checker/java_type_checker/expressions.py
+++ b/java-type-checker/java_type_checker/expressions.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-from .types import Type
+from .types import Type, NoSuchMethod
class Expression(object):
@@ -31,6 +31,12 @@ def __init__(self, name, declared_type):
self.name = name #: The name of the variable
self.declared_type = declared_type #: The declared type of the variable (Type)
+ def static_type(self):
+ return self.declared_type
+
+ def check_types(self):
+ pass
+
class Literal(Expression):
""" A literal value entered in the code, e.g. `5` in the expression `x + 5`.
@@ -39,22 +45,69 @@ def __init__(self, value, type):
self.value = value #: The literal value, as a string
self.type = type #: The type of the literal (Type)
+ def static_type(self):
+ return self.type
+
+ def check_types(self):
+ pass
+
+
class NullLiteral(Literal):
def __init__(self):
super().__init__("null", Type.null)
+ def static_type(self):
+ return Type.null
+
+ def check_types(self):
+ pass
+
class MethodCall(Expression):
"""
A Java method invocation, i.e. `foo.bar(0, 1, 2)`.
"""
def __init__(self, receiver, method_name, *args):
- self.receiver = receiver
self.receiver = receiver #: The object whose method we are calling (Expression)
self.method_name = method_name #: The name of the method to call (String)
self.args = args #: The method arguments (list of Expressions)
+ def static_type(self):
+ return self.receiver.static_type().method_named(self.method_name).return_type
+
+ def check_types(self):
+ #check for the primitive error
+ if not self.receiver.static_type().is_instantiable:
+ raise JavaTypeError(
+ "Type {0} does not have methods".format(
+ self.receiver.static_type().name))
+
+ method = self.receiver.static_type().method_named(self.method_name)
+ expected_argument_types = method.argument_types
+ numOfMethodParameters = len(method.argument_types)
+
+
+ #If the length of methods are not the same
+ if (len(self.args) != numOfMethodParameters):
+ raise JavaTypeError(
+ "Wrong number of arguments for {0}: expected {1}, got {2}".format(
+ str(self.receiver.static_type().name) + "." + str(self.method_name) + "()",
+ numOfMethodParameters,
+ len(self.args)))
+
+ actual_argument_types = []
+ for i in range(len(self.args)):
+ actual_argument_types.append(self.args[i].static_type())
+
+ for i in range(len(expected_argument_types)):
+ if not actual_argument_types[i].is_subtype_of(expected_argument_types[i]):
+ raise JavaTypeError(
+ "{0} expects arguments of type {1}, but got {2}".format(
+ str(self.receiver.static_type().name) + "." + str(self.method_name) + "()",
+ names(expected_argument_types),
+ names(actual_argument_types)))
+
class ConstructorCall(Expression):
"""
@@ -64,6 +117,38 @@ def __init__(self, instantiated_type, *args):
self.instantiated_type = instantiated_type #: The type to instantiate (Type)
self.args = args #: Constructor arguments (list of Expressions)
+ def static_type(self):
+ return self.instantiated_type
+
+ def check_types(self):
+ #checking if it is the primitives types.
+ if not(self.instantiated_type.is_instantiable):
+ raise JavaTypeError(
+ "Type {0} is not instantiable".format(
+ self.instantiated_type.name))
+
+ list_of_expected_constructor_arguments = self.instantiated_type.constructor.argument_types
+
+ if (len(self.args) != len(list_of_expected_constructor_arguments)):
+ raise JavaTypeError(
+ "Wrong number of arguments for {0} constructor: expected {1}, got {2}".format(
+ self.instantiated_type.name,
+ len(list_of_expected_constructor_arguments),
+ len(self.args)
+ )
+ )
+
+ list_of_actual_argument_types = []
+ for i in range(len(self.args)):
+ list_of_actual_argument_types.append(self.args[i].static_type())
+
+ for i in range(len(list_of_expected_constructor_arguments)):
+ if not list_of_actual_argument_types[i].is_subtype_of(list_of_expected_constructor_arguments[i]):
+ raise JavaTypeError(
+ "{0} constructor expects arguments of type {1}, but got {2}".format(
+ self.instantiated_type.name,
+ names(list_of_expected_constructor_arguments),
+ names(list_of_actual_argument_types)))
class JavaTypeError(Exception):
""" Indicates a compile-time type error in an expression.
diff --git a/java-type-checker/java_type_checker/types.py b/java-type-checker/java_type_checker/types.py
index 465f7f4..d72c5df 100644
--- a/java-type-checker/java_type_checker/types.py
+++ b/java-type-checker/java_type_checker/types.py
@@ -12,7 +12,13 @@ def __init__(self, name, direct_supertypes=[]):
def is_subtype_of(self, other):
""" True if this type can be used where the other type is expected.
"""
- return True # TODO: implement
+ if (other is self):
+ return True
+ else:
+ for directsupertypes in self.direct_supertypes:
+ if (directsupertypes.is_subtype_of(other)):
+ return True
+ return False
def is_supertype_of(self, other):
""" Convenience counterpart to is_subtype_of().
@@ -71,7 +77,7 @@ class NullType(Type):
"""
def __init__(self):
super().__init__("null")
-
+ self.is_instantiable = False
class NoSuchMethod(Exception):
pass
diff --git a/java-type-checker/tests/test_null.py b/java-type-checker/tests/test_null.py
index 36693c2..6de11cb 100644
--- a/java-type-checker/tests/test_null.py
+++ b/java-type-checker/tests/test_null.py
@@ -13,7 +13,7 @@ def test_object_params_accept_null(self):
Equivalent Java:
Rectangle rect;
-
+https://github.com/khintk/comp394-type-modeling
rect.setFillColor(null);
"""
self.assertNoCompileErrors(
@@ -22,6 +22,7 @@ def test_object_params_accept_null(self):
"setFillColor",
NullLiteral()))
+
def test_cannot_call_method_on_null(self):
"""
Equivalent Java:
diff --git a/java-type-checker/tests/test_type_checking.py b/java-type-checker/tests/test_type_checking.py
index b10ef24..d544433 100644
--- a/java-type-checker/tests/test_type_checking.py
+++ b/java-type-checker/tests/test_type_checking.py
@@ -8,15 +8,15 @@
class TestTypeChecking(TypeTest):
- def test_variables_never_have_type_errors(self):
+ def test_variables_never_have_type_errors(self): #Pass
self.assertNoCompileErrors(
Variable("p", Graphics.point))
- def test_literals_never_have_type_errors(self):
+ def test_literals_never_have_type_errors(self): #Pass
self.assertNoCompileErrors(
Variable("3.72", Type.double))
- def test_simple_method_call_passes(self):
+ def test_simple_method_call_passes(self): #pass
"""
Equivalent Java:
@@ -29,7 +29,7 @@ def test_simple_method_call_passes(self):
Variable("p", Graphics.point),
"getX"))
- def test_flags_nonexistent_method(self):
+ def test_flags_nonexistent_method(self): #Pass
"""
Equivalent Java:
@@ -44,7 +44,7 @@ def test_flags_nonexistent_method(self):
Variable("p", Graphics.point),
"getZ"))
- def test_flags_too_many_arguments(self):
+ def test_flags_too_many_arguments(self): #Pass
"""
Equivalent Java:
@@ -61,7 +61,7 @@ def test_flags_too_many_arguments(self):
Literal("0.0", Type.double),
Literal("1.0", Type.double)))
- def test_flags_too_few_arguments(self):
+ def test_flags_too_few_arguments(self): #Pass
"""
Equivalent Java:
@@ -77,7 +77,7 @@ def test_flags_too_few_arguments(self):
"setPosition",
Literal("0.0", Type.double)))
- def test_flags_wrong_argument_type(self):
+ def test_flags_wrong_argument_type(self): #Pass
"""
Equivalent Java:
@@ -94,7 +94,7 @@ def test_flags_wrong_argument_type(self):
Literal("0.0", Type.double),
Literal("true", Type.boolean)))
- def test_allows_subtypes_for_arguments(self):
+ def test_allows_subtypes_for_arguments(self): #Pass
"""
Equivalent Java:
@@ -109,7 +109,7 @@ def test_allows_subtypes_for_arguments(self):
"setFillColor",
Variable("red", Graphics.color)))
- def test_flags_wrong_number_of_constructor_arguments(self):
+ def test_flags_wrong_number_of_constructor_arguments(self): #Pass
"""
Equivalent Java:
@@ -124,7 +124,7 @@ def test_flags_wrong_number_of_constructor_arguments(self):
Graphics.rectangle,
Variable("p", Graphics.point)))
- def test_flags_wrong_constructor_argument_type(self):
+ def test_flags_wrong_constructor_argument_type(self): #Fail
"""
Equivalent Java:
@@ -140,7 +140,7 @@ def test_flags_wrong_constructor_argument_type(self):
Variable("p", Graphics.point),
Literal("true", Type.boolean)))
- def test_cannot_call_methods_on_primitives(self):
+ def test_cannot_call_methods_on_primitives(self): # Pass
"""
Equivalent Java:
@@ -160,14 +160,14 @@ def test_cannot_call_methods_on_primitives(self):
new int()
"""
- def test_cannot_instantiate_primitives(self):
+ def test_cannot_instantiate_primitives(self): #Pass
self.assertCompileError(
JavaTypeError,
"Type int is not instantiable",
ConstructorCall(
Type.int))
- def test_does_not_allow_void_passed_as_argument(self):
+ def test_does_not_allow_void_passed_as_argument(self): #Fail
"""
Equivalent Java:
@@ -188,7 +188,7 @@ def test_does_not_allow_void_passed_as_argument(self):
"setStrokeColor",
Variable("red", Graphics.color))))
- def test_passes_deep_expression(self):
+ def test_passes_deep_expression(self): #Fail
"""
Equivalent Java:
@@ -213,7 +213,7 @@ def test_passes_deep_expression(self):
Variable("window", Graphics.window),
"getSize"))))
- def test_catch_wrong_name_in_deep_expression(self):
+ def test_catch_wrong_name_in_deep_expression(self): #Fail
"""
Equivalent Java:
diff --git a/python-attr-lookup/python-attr-lookup.iml b/python-attr-lookup/python-attr-lookup.iml
index 01e8e1b..c514cf2 100644
--- a/python-attr-lookup/python-attr-lookup.iml
+++ b/python-attr-lookup/python-attr-lookup.iml
@@ -9,12 +9,10 @@
-
+
-
-
-
-
+
+
diff --git a/python-attr-lookup/src/plang/PythonObject.java b/python-attr-lookup/src/plang/PythonObject.java
index a8e311f..321bb27 100644
--- a/python-attr-lookup/src/plang/PythonObject.java
+++ b/python-attr-lookup/src/plang/PythonObject.java
@@ -1,10 +1,6 @@
package plang;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
/**
* The runtime state of an object in Python.
@@ -51,7 +47,10 @@ public List getMRO() {
* result (i.e. it remembers the list buildMRO() returned and keeps returning it).
*/
protected List buildMRO() {
- throw new UnsupportedOperationException("not implemented yet");
+ List resultMRO = new ArrayList<>();
+ resultMRO.add(this); //adding the self
+ resultMRO.addAll(this.getType().getMRO()); //adding the subclasses
+ return resultMRO;
}
/**
@@ -62,8 +61,16 @@ protected List buildMRO() {
* @throws PythonAttributeException When there is no attribute on this object with that name.
*/
public final PythonObject get(String attrName) throws PythonAttributeException {
- throw new UnsupportedOperationException("not implemented yet");
- }
+
+ List mroresults = getMRO();
+ for (int i = 0; i < mroresults.size(); i++) {
+ if (mroresults.get(i).attrs.containsKey(attrName)) {
+ return mroresults.get(i).attrs.get(attrName);
+ }
+ }
+ throw new PythonAttributeException(this, attrName);
+ }
+
/**
* Add or changes the value of an attribute on this object. Note that it sets the value for
@@ -73,8 +80,9 @@ public final PythonObject get(String attrName) throws PythonAttributeException {
* @param attrName The name of the attribute to set
* @param value Its new value
*/
+
public final void set(String attrName, PythonObject value) {
- throw new UnsupportedOperationException("not implemented yet");
+ this.attrs.put(attrName,value);
}
@Override
diff --git a/python-attr-lookup/src/plang/PythonType.java b/python-attr-lookup/src/plang/PythonType.java
index 4e2be4a..35b981e 100644
--- a/python-attr-lookup/src/plang/PythonType.java
+++ b/python-attr-lookup/src/plang/PythonType.java
@@ -19,6 +19,7 @@ public class PythonType extends PythonObject {
* (In real Python, instead of null it would be the class called `object`, and
* it would be a list instead of a single value.)
*/
+
public PythonType(String name, PythonObject base) {
super(null); // In real Python, this would be the type called `type`
this.name = name;
@@ -29,6 +30,7 @@ public PythonType(String name, PythonObject base) {
* The name of this class.
*/
public String getName() {
+
return name;
}
@@ -36,12 +38,18 @@ public String getName() {
* The base type (superclass) of this class.
*/
public PythonObject getBase() {
+
return base;
}
@Override
protected List buildMRO() {
- throw new UnsupportedOperationException("not implemented yet");
+ List resultMRO = new ArrayList<>();
+ resultMRO.add(this);
+ if (this.getBase() != null){
+ resultMRO.addAll(this.getBase().getMRO());
+ }
+ return resultMRO;
}
/**
@@ -49,7 +57,8 @@ protected List buildMRO() {
* this PythonType.
*/
public PythonObject instantiate() {
- throw new UnsupportedOperationException("not implemented yet");
+ PythonObject instance = new PythonObject(this);
+ return instance;
}
@Override
diff --git a/python-attr-lookup/test/plang/PythonObjectTest.java b/python-attr-lookup/test/plang/PythonObjectTest.java
index 9fa0483..d813030 100644
--- a/python-attr-lookup/test/plang/PythonObjectTest.java
+++ b/python-attr-lookup/test/plang/PythonObjectTest.java
@@ -8,13 +8,13 @@
import static org.junit.jupiter.api.Assertions.*;
+
class PythonObjectTest {
private PythonType fooType;
private PythonType barType;
private PythonObject foo;
private PythonObject bar;
-
/**
* Equivalent Python:
*
@@ -100,7 +100,7 @@ void objectsSupportNullValues() throws Exception {
assertEquals(null, foo.get("worries")); // No exception!
}
- @Test
+ @Test //didnt pass
void findInheritedAttrs() throws Exception {
// Equivalent Python:
//
@@ -116,7 +116,7 @@ void findInheritedAttrs() throws Exception {
assertEqualsPyStr("rainbow", bar.get("socks"));
}
- @Test
+ @Test //didnt pass
void overrideInheritedAttrsInType() throws Exception {
// Equivalent Python:
//
@@ -132,7 +132,7 @@ void overrideInheritedAttrsInType() throws Exception {
assertEqualsPyStr("polka dot", bar.get("socks"));
}
- @Test
+ @Test //didnt pass
void overrideInheritedAttrsInInstance() throws Exception {
// Equivalent Python:
//
@@ -149,7 +149,7 @@ void overrideInheritedAttrsInInstance() throws Exception {
}
- @Test
+ @Test //didnt pass
void overrideInheritedAttrsWithNull() throws Exception {
// Equivalent Python:
//