Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Completed the assignment! #16

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
2 changes: 1 addition & 1 deletion java-type-checker/.idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion java-type-checker/.idea/type-checker.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

89 changes: 87 additions & 2 deletions java-type-checker/java_type_checker/expressions.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-

from .types import Type
from .types import Type, NoSuchMethod


class Expression(object):
Expand Down Expand Up @@ -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`.
Expand All @@ -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):
"""
Expand All @@ -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.
Expand Down
10 changes: 8 additions & 2 deletions java-type-checker/java_type_checker/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -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().
Expand Down Expand Up @@ -71,7 +77,7 @@ class NullType(Type):
"""
def __init__(self):
super().__init__("null")

self.is_instantiable = False

class NoSuchMethod(Exception):
pass
Expand Down
3 changes: 2 additions & 1 deletion java-type-checker/tests/test_null.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -22,6 +22,7 @@ def test_object_params_accept_null(self):
"setFillColor",
NullLiteral()))


def test_cannot_call_method_on_null(self):
"""
Equivalent Java:
Expand Down
30 changes: 15 additions & 15 deletions java-type-checker/tests/test_type_checking.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand All @@ -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:

Expand All @@ -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:

Expand All @@ -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:

Expand All @@ -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:

Expand All @@ -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:

Expand All @@ -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:

Expand All @@ -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:

Expand All @@ -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:

Expand All @@ -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:

Expand All @@ -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:

Expand All @@ -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:

Expand Down
8 changes: 3 additions & 5 deletions python-attr-lookup/python-attr-lookup.iml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,10 @@
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module-library" scope="TEST">
<library name="JUnit5.0">
<library name="JUnit5">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/junit/jupiter/junit-jupiter-api/5.0.0/junit-jupiter-api-5.0.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/apiguardian/apiguardian-api/1.0.0/apiguardian-api-1.0.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/opentest4j/opentest4j/1.0.0/opentest4j-1.0.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/junit/platform/junit-platform-commons/1.0.0/junit-platform-commons-1.0.0.jar!/" />
<root url="jar://$APPLICATION_HOME_DIR$/plugins/junit/lib/junit-jupiter-api-5.0.0-RC2.jar!/" />
<root url="jar://$APPLICATION_HOME_DIR$/plugins/junit/lib/opentest4j-1.0.0-RC1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
Expand Down
26 changes: 17 additions & 9 deletions python-attr-lookup/src/plang/PythonObject.java
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -51,7 +47,10 @@ public List<PythonObject> getMRO() {
* result (i.e. it remembers the list buildMRO() returned and keeps returning it).
*/
protected List<PythonObject> buildMRO() {
throw new UnsupportedOperationException("not implemented yet");
List<PythonObject> resultMRO = new ArrayList<>();
resultMRO.add(this); //adding the self
resultMRO.addAll(this.getType().getMRO()); //adding the subclasses
return resultMRO;
}

/**
Expand All @@ -62,8 +61,16 @@ protected List<PythonObject> 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 <PythonObject> 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
Expand All @@ -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
Expand Down
Loading