commit b758a071dc0208960495f7a5ce305d3241ddf3af
Author: github-classroom[bot] <66690702+github-classroom[bot]@users.noreply.github.com>
Date: Wed Mar 3 14:08:57 2021 +0000
Initial commit
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..21cc758
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,149 @@
+.DS_Store
+__pycache__
+target
+
+# Created by https://www.gitignore.io/api/java,eclipse,intellij,emacs,vim
+
+### Java ###
+*.class
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
+
+### Eclipse ###
+*.pydevproject
+.metadata
+.gradle
+bin/
+tmp/
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.settings/
+.loadpath
+
+# Eclipse Core
+.project
+
+# External tool builders
+.externalToolBuilders/
+
+# Locally stored "Eclipse launch configurations"
+*.launch
+
+# CDT-specific
+.cproject
+
+# JDT-specific (Eclipse Java Development Tools)
+.classpath
+
+# Java annotation processor (APT)
+.factorypath
+
+# PDT-specific
+.buildpath
+
+# sbteclipse plugin
+.target
+
+# TeXlipse plugin
+.texlipse
+
+
+### Intellij ###
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio
+
+*.iml
+
+## Directory-based project format:
+.idea/
+# if you remove the above rule, at least ignore the following:
+
+# User-specific stuff:
+# .idea/workspace.xml
+# .idea/tasks.xml
+# .idea/dictionaries
+
+# Sensitive or high-churn files:
+# .idea/dataSources.ids
+# .idea/dataSources.xml
+# .idea/sqlDataSources.xml
+# .idea/dynamic.xml
+# .idea/uiDesigner.xml
+
+# Gradle:
+# .idea/gradle.xml
+# .idea/libraries
+
+# Mongo Explorer plugin:
+# .idea/mongoSettings.xml
+
+## File-based project format:
+*.ipr
+*.iws
+
+## Plugin-specific files:
+
+# IntelliJ
+/out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+
+
+### Emacs ###
+# -*- mode: gitignore; -*-
+*~
+\#*\#
+/.emacs.desktop
+/.emacs.desktop.lock
+*.elc
+auto-save-list
+tramp
+.\#*
+
+# Org-mode
+.org-id-locations
+*_archive
+
+# flymake-mode
+*_flymake.*
+
+# eshell files
+/eshell/history
+/eshell/lastdir
+
+# elpa packages
+/elpa/
+
+# reftex files
+*.rel
+
+# AUCTeX auto folder
+/auto/
+
+# cask packages
+.cask/
+
+
+### Vim ###
+[._]*.s[a-w][a-z]
+[._]s[a-w][a-z]
+*.un~
+Session.vim
+.netrwhist
+*~
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..0808d4b
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,26 @@
+Copyright (c) 2017-2018 The Regents of the University of California
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..6716c27
--- /dev/null
+++ b/README.md
@@ -0,0 +1,35 @@
+# NYU Compiler Construction CSCI-GA.2130/Spring 2021: Programming Assignment 2
+
+This assignment is adapted from https://github.com/cs164berkeley/pa2-chocopy-semantic-analysis with the authors' permission.
+
+See the PA2 document on Piazza for a detailed specification.
+
+## Quickstart
+
+Run the following commands to compile your analyzer and run the tests:
+```
+mvn clean package
+java -cp "chocopy-ref.jar:target/assignment.jar" chocopy.ChocoPy \
+ --pass=.s --test --dir src/test/data/pa2/sample/
+```
+
+The dot in `--pass` makes the compiler skip parsing and go straight to semantic analysis.
+`--pass=.s` uses your (`s` for `student`) analyzer to perform semantic analysis on a preparsed input (in this case, the `.ast` files under `src/test/data/pa2/sample/`).
+With the starter code, only two tests should pass.
+Your main objective is to build an analyzer that passes all the provided tests.
+
+`--pass=.r` uses the reference (`r` for `reference`) analyzer, which should pass all tests.
+
+In addition to running in test mode with `--test`, you can also observe the actual output of your (or reference) analyzer with:
+```
+java -cp "chocopy-ref.jar:target/assignment.jar" chocopy.ChocoPy \
+ --pass=.s src/test/data/pa2/sample/expr_unary.py.ast
+```
+
+You can also run both passes on the original `.py` file:
+```
+java -cp "chocopy-ref.jar:target/assignment.jar" chocopy.ChocoPy \
+ --pass=rr src/test/data/pa2/sample/expr_unary.py
+```
+
+Once you merge your parser code from assignment 1, you should be able to use `--pass=ss`.
diff --git a/chocopy-ref.jar b/chocopy-ref.jar
new file mode 100644
index 0000000..a497f25
Binary files /dev/null and b/chocopy-ref.jar differ
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..1766e51
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,330 @@
+
+ 4.0.0
+ chocopy
+ chocopy
+ jar
+ 2.2-SNAPSHOT
+ chocopy
+ http://maven.apache.org
+
+
+
+ false
+
+
+
+
+
+
+
+ de.jflex
+ jflex-maven-plugin
+ 1.6.1
+
+
+ com.github.vbmacher
+ cup-maven-plugin
+ 11b-20160615
+
+
+ maven-assembly-plugin
+ 3.1.0
+
+
+ maven-jar-plugin
+ 3.1.0
+
+
+ maven-site-plugin
+ 3.7.1
+
+
+
+
+
+
+ maven-assembly-plugin
+
+
+ jar-with-dependencies
+
+ assignment
+ false
+
+
+
+ make-assembly
+ package
+
+ single
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.0
+
+ UTF-8
+ 1.8
+ 1.8
+ true
+ true
+
+
+
+
+
+
+ src/main/asm
+
+ **/*.s
+ **/*.os
+
+
+ **/reference/*.s
+
+
+
+
+
+
+
+ reference
+
+
+
+ src/main/java/chocopy/reference/
+
+
+
+
+
+
+ maven-jar-plugin
+
+
+ **/pa1/*
+ **/pa2/*
+ **/pa3/*
+
+
+
+
+
+ maven-assembly-plugin
+
+
+ jar-with-dependencies
+
+ chocopy-ref
+ false
+
+
+
+
+ de.jflex
+ jflex-maven-plugin
+
+
+ jflex-reference
+
+ generate
+
+
+
+ src/main/jflex/chocopy/reference/ChocoPy.jflex
+
+ ${chocopy.debug}
+ true
+
+
+
+
+
+
+ com.github.vbmacher
+ cup-maven-plugin
+
+
+ cup-reference
+
+ generate
+
+
+ src/main/cup/chocopy/reference/ChocoPy.cup
+ chocopy.reference
+ ChocoPyParser
+ ChocoPyTokens
+ ${chocopy.debug}
+ ${chocopy.debug}
+ ${chocopy.debug}
+ true
+
+
+
+
+
+
+ maven-compiler-plugin
+
+ true
+ none
+
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+ 3.1.1
+
+
+ copy-dependencies
+ package
+
+ copy-dependencies
+
+
+
+
+
+
+
+
+
+ pa1
+
+
+
+ src/main/java/chocopy/pa1
+
+
+
+
+
+
+ de.jflex
+ jflex-maven-plugin
+
+
+ jflex-pa1
+
+ generate
+
+
+
+ src/main/jflex/chocopy/pa1/ChocoPy.jflex
+
+ ${chocopy.debug}
+ true
+
+
+
+
+
+
+ com.github.vbmacher
+ cup-maven-plugin
+
+
+ cup-pa1
+
+ generate
+
+
+ src/main/cup/chocopy/pa1/ChocoPy.cup
+ chocopy.pa1
+ ChocoPyParser
+ ChocoPyTokens
+ ${chocopy.debug}
+ ${chocopy.debug}
+ ${chocopy.debug}
+ true
+
+
+
+
+
+
+
+
+ pa2
+
+
+
+ src/main/java/chocopy/pa2
+
+
+
+
+ pa3
+
+
+
+ src/main/java/chocopy/pa3
+
+
+
+
+
+
+
+
+ venus164-repo
+ Repository for Venus164
+ https://raw.githubusercontent.com/chocopy/venus/maven-repository/
+
+
+
+
+
+ net.sourceforge.argparse4j
+ argparse4j
+ 0.8.1
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ [2.9.10.1,)
+
+
+ com.fasterxml.jackson.module
+ jackson-module-parameter-names
+ 2.9.10
+
+
+ com.github.vbmacher
+ java-cup-runtime
+ 11b-20160615
+
+
+
+ de.jflex
+ jflex
+ 1.6.1
+
+
+ org.jetbrains.kotlin
+ kotlin-stdlib
+ 1.2.71
+
+
+ edu.berkeley.eecs.venus164
+ venus164
+ 0.2.4
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+ net.sf.proguard
+ proguard-base
+ 6.0.3
+
+
+
diff --git a/src/main/java/chocopy/common/Utils.java b/src/main/java/chocopy/common/Utils.java
new file mode 100644
index 0000000..aefd409
--- /dev/null
+++ b/src/main/java/chocopy/common/Utils.java
@@ -0,0 +1,54 @@
+package chocopy.common;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.stream.Collectors;
+
+/** Utility functions for general use. */
+public class Utils {
+
+ /**
+ * Return resource file FILENAME's contents as a string. FILENAME can refer to a file within the
+ * class hierarchy, so that a text resource in file resource.txt in the chocopy.common.codegen
+ * package, for example, could be referred to with FILENAME chocopy/common/codegen/resource.txt.
+ *
+ *
Credit: Lucio Paiva.
+ */
+ public static String getResourceFileAsString(String fileName) {
+ InputStream is = Utils.class.getClassLoader().getResourceAsStream(fileName);
+ if (is != null) {
+ BufferedReader reader =
+ new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
+ return reader.lines().collect(Collectors.joining(System.lineSeparator()));
+ }
+ return null;
+ }
+
+ /**
+ * Return an exception signalling a fatal error having a message formed from MSGFORMAT and ARGS,
+ * as for String.format.
+ */
+ public static Error fatal(String msgFormat, Object... args) {
+ return new Error(String.format(msgFormat, args));
+ }
+
+ /**
+ * Return the string S padded with FILL to TOLEN characters. Padding is on the left if
+ * PADONLEFT, and otherwise on the right. If S is already at least TOLEN characters, returns S.
+ */
+ public static String pad(String s, Character fill, int toLen, boolean padOnLeft) {
+ StringBuilder result = new StringBuilder(toLen);
+ if (!padOnLeft) {
+ result.append(s);
+ }
+ for (int n = s.length(); n < toLen; n += 1) {
+ result.append(fill);
+ }
+ if (padOnLeft) {
+ result.append(s);
+ }
+ return result.toString();
+ }
+}
diff --git a/src/main/java/chocopy/common/analysis/AbstractNodeAnalyzer.java b/src/main/java/chocopy/common/analysis/AbstractNodeAnalyzer.java
new file mode 100644
index 0000000..7225c2b
--- /dev/null
+++ b/src/main/java/chocopy/common/analysis/AbstractNodeAnalyzer.java
@@ -0,0 +1,174 @@
+package chocopy.common.analysis;
+
+import chocopy.common.astnodes.*;
+
+/**
+ * An empty implementation of the {@link NodeAnalyzer} that simply returns does nothing and returns
+ * null for every AST node type.
+ *
+ *
T is the type of analysis result.
+ */
+public class AbstractNodeAnalyzer implements NodeAnalyzer {
+ @Override
+ public T analyze(AssignStmt node) {
+ return defaultAction(node);
+ }
+
+ @Override
+ public T analyze(BinaryExpr node) {
+ return defaultAction(node);
+ }
+
+ @Override
+ public T analyze(BooleanLiteral node) {
+ return defaultAction(node);
+ }
+
+ @Override
+ public T analyze(CallExpr node) {
+ return defaultAction(node);
+ }
+
+ @Override
+ public T analyze(ClassDef node) {
+ return defaultAction(node);
+ }
+
+ @Override
+ public T analyze(ClassType node) {
+ return defaultAction(node);
+ }
+
+ @Override
+ public T analyze(CompilerError node) {
+ return defaultAction(node);
+ }
+
+ @Override
+ public T analyze(Errors node) {
+ return defaultAction(node);
+ }
+
+ @Override
+ public T analyze(ExprStmt node) {
+ return defaultAction(node);
+ }
+
+ @Override
+ public T analyze(ForStmt node) {
+ return defaultAction(node);
+ }
+
+ @Override
+ public T analyze(FuncDef node) {
+ return defaultAction(node);
+ }
+
+ @Override
+ public T analyze(GlobalDecl node) {
+ return defaultAction(node);
+ }
+
+ @Override
+ public T analyze(Identifier node) {
+ return defaultAction(node);
+ }
+
+ @Override
+ public T analyze(IfExpr node) {
+ return defaultAction(node);
+ }
+
+ @Override
+ public T analyze(IfStmt node) {
+ return defaultAction(node);
+ }
+
+ @Override
+ public T analyze(IndexExpr node) {
+ return defaultAction(node);
+ }
+
+ @Override
+ public T analyze(IntegerLiteral node) {
+ return defaultAction(node);
+ }
+
+ @Override
+ public T analyze(ListExpr node) {
+ return defaultAction(node);
+ }
+
+ @Override
+ public T analyze(ListType node) {
+ return defaultAction(node);
+ }
+
+ @Override
+ public T analyze(MemberExpr node) {
+ return defaultAction(node);
+ }
+
+ @Override
+ public T analyze(MethodCallExpr node) {
+ return defaultAction(node);
+ }
+
+ @Override
+ public T analyze(NoneLiteral node) {
+ return defaultAction(node);
+ }
+
+ @Override
+ public T analyze(NonLocalDecl node) {
+ return defaultAction(node);
+ }
+
+ @Override
+ public T analyze(Program node) {
+ return defaultAction(node);
+ }
+
+ @Override
+ public T analyze(ReturnStmt node) {
+ return defaultAction(node);
+ }
+
+ @Override
+ public T analyze(StringLiteral node) {
+ return defaultAction(node);
+ }
+
+ @Override
+ public T analyze(TypedVar node) {
+ return defaultAction(node);
+ }
+
+ @Override
+ public T analyze(UnaryExpr node) {
+ return defaultAction(node);
+ }
+
+ @Override
+ public T analyze(VarDef node) {
+ return defaultAction(node);
+ }
+
+ @Override
+ public T analyze(WhileStmt node) {
+ return defaultAction(node);
+ }
+
+ @Override
+ public void setDefault(T value) {
+ defaultValue = value;
+ }
+
+ @Override
+ public T defaultAction(Node node) {
+ return defaultValue;
+ }
+
+ /** Default value for non-overridden methods. */
+ private T defaultValue = null;
+}
diff --git a/src/main/java/chocopy/common/analysis/NodeAnalyzer.java b/src/main/java/chocopy/common/analysis/NodeAnalyzer.java
new file mode 100644
index 0000000..2326fbc
--- /dev/null
+++ b/src/main/java/chocopy/common/analysis/NodeAnalyzer.java
@@ -0,0 +1,93 @@
+package chocopy.common.analysis;
+
+import chocopy.common.astnodes.*;
+
+/**
+ * This interface can be used to separate logic for various concrete classes in the AST class
+ * hierarchy.
+ *
+ * The idea is that a phase of the analysis is encapsulated in a class that implements this
+ * interface, and contains an overriding of the analyze method for each concrete Node class that
+ * needs something other than default processing. Each concrete node class, C, implements a generic
+ * dispatch method that takes a NodeAnalyzer argument and calls the overloading of analyze that
+ * takes an argument of type C. The effect is that anode.dispatch(anAnalyzer) executes the method
+ * anAnalyzer.analyze that is appropriate to aNode's dynamic type. As a result each NodeAnalyzer
+ * subtype encapsulates all implementations of a particular action on Nodes. Thus, it inverts the
+ * usual OO pattern in which the implementations of analysis A for each different class are
+ * scattered among the class bodies themselves as overridings of a method A on the Node class.
+ *
+ * The class AbstractNodeAnalyzer provides empty default implementations for these methods.
+ *
+ *
The type T is the type of result returned by the encapsulated analysis.
+ */
+public interface NodeAnalyzer {
+
+ T analyze(AssignStmt node);
+
+ T analyze(BinaryExpr node);
+
+ T analyze(BooleanLiteral node);
+
+ T analyze(CallExpr node);
+
+ T analyze(ClassDef node);
+
+ T analyze(ClassType node);
+
+ T analyze(CompilerError node);
+
+ T analyze(Errors node);
+
+ T analyze(ExprStmt node);
+
+ T analyze(ForStmt node);
+
+ T analyze(FuncDef node);
+
+ T analyze(GlobalDecl node);
+
+ T analyze(Identifier node);
+
+ T analyze(IfExpr node);
+
+ T analyze(IfStmt node);
+
+ T analyze(IndexExpr node);
+
+ T analyze(IntegerLiteral node);
+
+ T analyze(ListExpr node);
+
+ T analyze(ListType node);
+
+ T analyze(MemberExpr node);
+
+ T analyze(MethodCallExpr node);
+
+ T analyze(NoneLiteral node);
+
+ T analyze(NonLocalDecl node);
+
+ T analyze(Program node);
+
+ T analyze(ReturnStmt node);
+
+ T analyze(StringLiteral node);
+
+ T analyze(TypedVar node);
+
+ T analyze(UnaryExpr node);
+
+ T analyze(VarDef node);
+
+ T analyze(WhileStmt node);
+
+ /**
+ * Set the default value returned by calls to analyze that are not overridden to VALUE. By
+ * default, this is null.
+ */
+ void setDefault(T value);
+
+ /** Default value for non-overridden methods. */
+ T defaultAction(Node node);
+}
diff --git a/src/main/java/chocopy/common/analysis/SymbolTable.java b/src/main/java/chocopy/common/analysis/SymbolTable.java
new file mode 100644
index 0000000..bc22ac4
--- /dev/null
+++ b/src/main/java/chocopy/common/analysis/SymbolTable.java
@@ -0,0 +1,62 @@
+package chocopy.common.analysis;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A block-structured symbol table a mapping identifiers to information about them of type T in a
+ * given declarative region.
+ */
+public class SymbolTable {
+
+ /** Contents of the current (innermost) region. */
+ private final Map tab = new HashMap<>();
+ /** Enclosing block. */
+ private final SymbolTable parent;
+
+ /** A table representing a region nested in that represented by PARENT0. */
+ public SymbolTable(SymbolTable parent0) {
+ parent = parent0;
+ }
+
+ /** A top-level symbol table. */
+ public SymbolTable() {
+ this.parent = null;
+ }
+
+ /** Returns the mapping of NAME in the innermost nested region containing this one. */
+ public T get(String name) {
+ if (tab.containsKey(name)) {
+ return tab.get(name);
+ } else if (parent != null) {
+ return parent.get(name);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Adds a new mapping of NAME -> VALUE to the current region, possibly shadowing mappings in the
+ * enclosing parent. Returns modified table.
+ */
+ public SymbolTable put(String name, T value) {
+ tab.put(name, value);
+ return this;
+ }
+
+ /** Returns whether NAME has a mapping in this region (ignoring enclosing regions. */
+ public boolean declares(String name) {
+ return tab.containsKey(name);
+ }
+
+ /** Returns all the names declared this region (ignoring enclosing regions). */
+ public Set getDeclaredSymbols() {
+ return tab.keySet();
+ }
+
+ /** Returns the parent, or null if this is the top level. */
+ public SymbolTable getParent() {
+ return this.parent;
+ }
+}
diff --git a/src/main/java/chocopy/common/analysis/types/ClassValueType.java b/src/main/java/chocopy/common/analysis/types/ClassValueType.java
new file mode 100644
index 0000000..05c2e93
--- /dev/null
+++ b/src/main/java/chocopy/common/analysis/types/ClassValueType.java
@@ -0,0 +1,53 @@
+package chocopy.common.analysis.types;
+
+import chocopy.common.astnodes.ClassType;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.util.Objects;
+
+/** Represents the semantic value of a simple class reference. */
+public class ClassValueType extends ValueType {
+
+ /** The name of the class. */
+ private final String className;
+
+ /** A class type for the class named CLASSNAME. */
+ @JsonCreator
+ public ClassValueType(@JsonProperty String className) {
+ this.className = className;
+ }
+
+ /** A class type for the class referenced by CLASSTYPEANNOTATION. */
+ public ClassValueType(ClassType classTypeAnnotation) {
+ this.className = classTypeAnnotation.className;
+ }
+
+ @Override
+ @JsonProperty
+ public String className() {
+ return className;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ ClassValueType classType = (ClassValueType) o;
+ return Objects.equals(className, classType.className);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(className);
+ }
+
+ @Override
+ public String toString() {
+ return className;
+ }
+}
diff --git a/src/main/java/chocopy/common/analysis/types/FuncType.java b/src/main/java/chocopy/common/analysis/types/FuncType.java
new file mode 100644
index 0000000..69fdefc
--- /dev/null
+++ b/src/main/java/chocopy/common/analysis/types/FuncType.java
@@ -0,0 +1,45 @@
+package chocopy.common.analysis.types;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/** Semantic information for a function or method. */
+public class FuncType extends Type {
+
+ /** Types of parameters. */
+ public final List parameters;
+ /** Function's return type. */
+ public final ValueType returnType;
+
+ /** Create a FuncType returning RETURNTYPE0, initially parameterless. */
+ public FuncType(ValueType returnType0) {
+ this(new ArrayList<>(), returnType0);
+ }
+
+ /**
+ * Create a FuncType for NAME0 with formal parameter types PARAMETERS0, returning type
+ * RETURNTYPE0.
+ */
+ @JsonCreator
+ public FuncType(List parameters0, ValueType returnType0) {
+ this.parameters = parameters0;
+ this.returnType = returnType0;
+ }
+
+ @Override
+ public boolean isFuncType() {
+ return true;
+ }
+
+ /** Return the type of the K-th parameter. */
+ public ValueType getParamType(int k) {
+ return parameters.get(k);
+ }
+
+ @Override
+ public String toString() {
+ return "";
+ }
+}
diff --git a/src/main/java/chocopy/common/analysis/types/ListValueType.java b/src/main/java/chocopy/common/analysis/types/ListValueType.java
new file mode 100644
index 0000000..fae59c7
--- /dev/null
+++ b/src/main/java/chocopy/common/analysis/types/ListValueType.java
@@ -0,0 +1,57 @@
+package chocopy.common.analysis.types;
+
+import chocopy.common.astnodes.ListType;
+import com.fasterxml.jackson.annotation.JsonCreator;
+
+import java.util.Objects;
+
+/** Represents a semantic value of a list type denotation. */
+public class ListValueType extends ValueType {
+
+ /** This ListValueType represents [ELEMENTTYPE]. */
+ public final ValueType elementType;
+
+ /** Represents [ELEMENTTYPE]. */
+ @JsonCreator
+ public ListValueType(Type elementType) {
+ this.elementType = (ValueType) elementType;
+ }
+
+ /** Represents [], where is that denoted in TYPEANNOTATION. */
+ public ListValueType(ListType typeAnnotation) {
+ elementType = ValueType.annotationToValueType(typeAnnotation.elementType);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ ListValueType listType = (ListValueType) o;
+ return Objects.equals(elementType, listType.elementType);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(elementType);
+ }
+
+ @Override
+ public String toString() {
+ return "[" + elementType.toString() + "]";
+ }
+
+ /** Returns true iff I represent [T]. */
+ @Override
+ public boolean isListType() {
+ return true;
+ }
+
+ @Override
+ public ValueType elementType() {
+ return elementType;
+ }
+}
diff --git a/src/main/java/chocopy/common/analysis/types/Type.java b/src/main/java/chocopy/common/analysis/types/Type.java
new file mode 100644
index 0000000..2eddc37
--- /dev/null
+++ b/src/main/java/chocopy/common/analysis/types/Type.java
@@ -0,0 +1,68 @@
+package chocopy.common.analysis.types;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonSubTypes;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+
+/**
+ * Representation for the static type of symbols and expressions during type-checking.
+ *
+ * Symbols such as variables and attributes will typically map to a {@link ValueType}.
+ *
+ *
Symbols such as classes will typically map to a more complex Type.
+ */
+@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "kind")
+@JsonSubTypes({
+ @JsonSubTypes.Type(FuncType.class),
+ @JsonSubTypes.Type(ClassValueType.class),
+ @JsonSubTypes.Type(ListValueType.class)
+})
+public abstract class Type {
+
+ /** The type object. */
+ public static final ClassValueType OBJECT_TYPE = new ClassValueType("object");
+ /** The type int. */
+ public static final ClassValueType INT_TYPE = new ClassValueType("int");
+ /** The type str. */
+ public static final ClassValueType STR_TYPE = new ClassValueType("str");
+ /** The type bool. */
+ public static final ClassValueType BOOL_TYPE = new ClassValueType("bool");
+
+ /** The type of None. */
+ public static final ClassValueType NONE_TYPE = new ClassValueType("");
+ /** The type of []. */
+ public static final ClassValueType EMPTY_TYPE = new ClassValueType("");
+
+ /** Returns the name of the class, if this is a class type, Otherwise null. */
+ public String className() {
+ return null;
+ }
+
+ /** Return true iff this is a type that does not include the value None. */
+ @JsonIgnore
+ public boolean isSpecialType() {
+ return equals(INT_TYPE) || equals(BOOL_TYPE) || equals(STR_TYPE);
+ }
+
+ @JsonIgnore
+ public boolean isListType() {
+ return false;
+ }
+
+ @JsonIgnore
+ public boolean isFuncType() {
+ return false;
+ }
+
+ /** Return true iff this type represents a kind of assignable value. */
+ @JsonIgnore
+ public boolean isValueType() {
+ return false;
+ }
+
+ /** For list types, return the type of the elements; otherwise null. */
+ @JsonIgnore
+ public ValueType elementType() {
+ return null;
+ }
+}
diff --git a/src/main/java/chocopy/common/analysis/types/ValueType.java b/src/main/java/chocopy/common/analysis/types/ValueType.java
new file mode 100644
index 0000000..bb5d908
--- /dev/null
+++ b/src/main/java/chocopy/common/analysis/types/ValueType.java
@@ -0,0 +1,29 @@
+package chocopy.common.analysis.types;
+
+import chocopy.common.astnodes.ClassType;
+import chocopy.common.astnodes.ListType;
+import chocopy.common.astnodes.TypeAnnotation;
+
+/**
+ * A ValueType references types that are assigned to variables and expressions.
+ *
+ * In particular, ValueType can be a {@link ClassValueType} (e.g. "int") or a {@link
+ * ListValueType} (e.g. "[int]").
+ */
+public abstract class ValueType extends Type {
+
+ /** Returns the type corresponding to ANNOTATION. */
+ public static ValueType annotationToValueType(TypeAnnotation annotation) {
+ if (annotation instanceof ClassType) {
+ return new ClassValueType((ClassType) annotation);
+ } else {
+ assert annotation instanceof ListType;
+ return new ListValueType((ListType) annotation);
+ }
+ }
+
+ @Override
+ public boolean isValueType() {
+ return true;
+ }
+}
diff --git a/src/main/java/chocopy/common/astnodes/AssignStmt.java b/src/main/java/chocopy/common/astnodes/AssignStmt.java
new file mode 100644
index 0000000..1452463
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/AssignStmt.java
@@ -0,0 +1,25 @@
+package chocopy.common.astnodes;
+
+import chocopy.common.analysis.NodeAnalyzer;
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+import java.util.List;
+
+/** Single and multiple assignments. */
+public class AssignStmt extends Stmt {
+ /** List of left-hand sides. */
+ public final List targets;
+ /** Right-hand-side value to be assigned. */
+ public final Expr value;
+
+ /** AST for TARGETS[0] = TARGETS[1] = ... = VALUE spanning source locations [LEFT..RIGHT]. */
+ public AssignStmt(Location left, Location right, List targets, Expr value) {
+ super(left, right);
+ this.targets = targets;
+ this.value = value;
+ }
+
+ public T dispatch(NodeAnalyzer analyzer) {
+ return analyzer.analyze(this);
+ }
+}
diff --git a/src/main/java/chocopy/common/astnodes/BinaryExpr.java b/src/main/java/chocopy/common/astnodes/BinaryExpr.java
new file mode 100644
index 0000000..f4ce05b
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/BinaryExpr.java
@@ -0,0 +1,31 @@
+package chocopy.common.astnodes;
+
+import chocopy.common.analysis.NodeAnalyzer;
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+/** . */
+public class BinaryExpr extends Expr {
+
+ /** Left operand. */
+ public final Expr left;
+ /** Operator name. */
+ public final String operator;
+ /** Right operand. */
+ public final Expr right;
+
+ /**
+ * An AST for expressions of the form LEFTEXPR OP RIGHTEXPR from text in range
+ * [LEFTLOC..RIGHTLOC].
+ */
+ public BinaryExpr(
+ Location leftLoc, Location rightLoc, Expr leftExpr, String op, Expr rightExpr) {
+ super(leftLoc, rightLoc);
+ left = leftExpr;
+ operator = op;
+ right = rightExpr;
+ }
+
+ public T dispatch(NodeAnalyzer analyzer) {
+ return analyzer.analyze(this);
+ }
+}
diff --git a/src/main/java/chocopy/common/astnodes/BooleanLiteral.java b/src/main/java/chocopy/common/astnodes/BooleanLiteral.java
new file mode 100644
index 0000000..ffce126
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/BooleanLiteral.java
@@ -0,0 +1,21 @@
+package chocopy.common.astnodes;
+
+import chocopy.common.analysis.NodeAnalyzer;
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+/** Literals True or False. */
+public final class BooleanLiteral extends Literal {
+
+ /** True iff I represent True. */
+ public final boolean value;
+
+ /** An AST for the token True or False at [LEFT..RIGHT], depending on VALUE. */
+ public BooleanLiteral(Location left, Location right, boolean value) {
+ super(left, right);
+ this.value = value;
+ }
+
+ public T dispatch(NodeAnalyzer analyzer) {
+ return analyzer.analyze(this);
+ }
+}
diff --git a/src/main/java/chocopy/common/astnodes/CallExpr.java b/src/main/java/chocopy/common/astnodes/CallExpr.java
new file mode 100644
index 0000000..84f13ae
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/CallExpr.java
@@ -0,0 +1,26 @@
+package chocopy.common.astnodes;
+
+import chocopy.common.analysis.NodeAnalyzer;
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+import java.util.List;
+
+/** A function call. */
+public class CallExpr extends Expr {
+
+ /** The called function. */
+ public final Identifier function;
+ /** The actual parameter expressions. */
+ public final List args;
+
+ /** AST for FUNCTION(ARGS) at [LEFT..RIGHT]. */
+ public CallExpr(Location left, Location right, Identifier function, List args) {
+ super(left, right);
+ this.function = function;
+ this.args = args;
+ }
+
+ public T dispatch(NodeAnalyzer analyzer) {
+ return analyzer.analyze(this);
+ }
+}
diff --git a/src/main/java/chocopy/common/astnodes/ClassDef.java b/src/main/java/chocopy/common/astnodes/ClassDef.java
new file mode 100644
index 0000000..63531c8
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/ClassDef.java
@@ -0,0 +1,39 @@
+package chocopy.common.astnodes;
+
+import chocopy.common.analysis.NodeAnalyzer;
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+import java.util.List;
+
+/** A class definition. */
+public class ClassDef extends Declaration {
+
+ /** Name of the declared class. */
+ public final Identifier name;
+ /** Name of the parent class. */
+ public final Identifier superClass;
+ /** Body of the class. */
+ public final List declarations;
+
+ /** An AST for class NAME(SUPERCLASS): DECLARATIONS. spanning source locations [LEFT..RIGHT]. */
+ public ClassDef(
+ Location left,
+ Location right,
+ Identifier name,
+ Identifier superClass,
+ List declarations) {
+ super(left, right);
+ this.name = name;
+ this.superClass = superClass;
+ this.declarations = declarations;
+ }
+
+ public T dispatch(NodeAnalyzer analyzer) {
+ return analyzer.analyze(this);
+ }
+
+ @Override
+ public Identifier getIdentifier() {
+ return this.name;
+ }
+}
diff --git a/src/main/java/chocopy/common/astnodes/ClassType.java b/src/main/java/chocopy/common/astnodes/ClassType.java
new file mode 100644
index 0000000..fd4cd4d
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/ClassType.java
@@ -0,0 +1,21 @@
+package chocopy.common.astnodes;
+
+import chocopy.common.analysis.NodeAnalyzer;
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+/** A simple class type name. */
+public final class ClassType extends TypeAnnotation {
+
+ /** The denotation of the class in source. */
+ public final String className;
+
+ /** An AST denoting a type named CLASSNAME0 at [LEFT..RIGHT]. */
+ public ClassType(Location left, Location right, String className0) {
+ super(left, right);
+ className = className0;
+ }
+
+ public T dispatch(NodeAnalyzer analyzer) {
+ return analyzer.analyze(this);
+ }
+}
diff --git a/src/main/java/chocopy/common/astnodes/CompilerError.java b/src/main/java/chocopy/common/astnodes/CompilerError.java
new file mode 100644
index 0000000..81cc5bb
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/CompilerError.java
@@ -0,0 +1,56 @@
+package chocopy.common.astnodes;
+
+import chocopy.common.analysis.NodeAnalyzer;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+import java.util.Arrays;
+import java.util.Objects;
+
+/** Represents a single error. Does not correspond to any Python source construct. */
+public class CompilerError extends Node {
+
+ /**
+ * Represents an error with message MESSAGE. Iff SYNTAX, it is a syntactic error. The error
+ * applies to source text at [LEFT..RIGHT].
+ */
+ public CompilerError(Location left, Location right, String message, boolean syntax) {
+ super(left, right);
+ this.message = message;
+ this.syntax = syntax;
+ }
+
+ @JsonInclude(JsonInclude.Include.NON_DEFAULT)
+ public boolean isSyntax() {
+ return syntax;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ CompilerError that = (CompilerError) o;
+ return Objects.equals(message, that.message)
+ && Arrays.equals(getLocation(), that.getLocation());
+ }
+
+ @Override
+ public int hashCode() {
+ int result = Objects.hash(message);
+ result = 31 * result + Arrays.hashCode(getLocation());
+ return result;
+ }
+
+ public T dispatch(NodeAnalyzer analyzer) {
+ return analyzer.analyze(this);
+ }
+
+ /** The error message. */
+ public final String message;
+ /** True if this is a syntax error. */
+ private final boolean syntax;
+}
diff --git a/src/main/java/chocopy/common/astnodes/Declaration.java b/src/main/java/chocopy/common/astnodes/Declaration.java
new file mode 100644
index 0000000..0faa921
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/Declaration.java
@@ -0,0 +1,17 @@
+package chocopy.common.astnodes;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+/** Base of all AST nodes representing definitions or declarations. */
+public abstract class Declaration extends Node {
+
+ /** A definition or declaration spanning source locations [LEFT..RIGHT]. */
+ public Declaration(Location left, Location right) {
+ super(left, right);
+ }
+
+ /** Return the identifier defined by this Declaration. */
+ @JsonIgnore
+ public abstract Identifier getIdentifier();
+}
diff --git a/src/main/java/chocopy/common/astnodes/Errors.java b/src/main/java/chocopy/common/astnodes/Errors.java
new file mode 100644
index 0000000..86240dd
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/Errors.java
@@ -0,0 +1,71 @@
+package chocopy.common.astnodes;
+
+import chocopy.common.analysis.NodeAnalyzer;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+import java.util.List;
+
+/** Collects the error messages in a Program. There is exactly one per Program node. */
+public class Errors extends Node {
+
+ /** The accumulated error messages in the order added. */
+ public final List errors;
+
+ /** True iff multiple semantic errors allowed on a node. */
+ @JsonIgnore private boolean allowMultipleErrors;
+
+ /**
+ * An Errors whose list of CompilerErrors is ERRORS. The list should be modified using this.add.
+ */
+ @JsonCreator
+ public Errors(List errors) {
+ super(null, null);
+ this.errors = errors;
+ allowMultipleErrors = true;
+ }
+
+ /** Return true iff there are any errors. */
+ public boolean hasErrors() {
+ return !this.errors.isEmpty();
+ }
+
+ /** Prevent multiple semantic errors on the same node. */
+ public void suppressMultipleErrors() {
+ allowMultipleErrors = false;
+ }
+
+ /**
+ * Add a new semantic error message attributed to NODE, with message String.format(MESSAGEFORM,
+ * ARGS).
+ */
+ public void semError(Node node, String messageForm, Object... args) {
+ if (allowMultipleErrors || !node.hasError()) {
+ String msg = String.format(messageForm, args);
+ CompilerError err = new CompilerError(null, null, msg, false);
+ err.setLocation(node.getLocation());
+ add(err);
+ if (!node.hasError()) {
+ node.setErrorMsg(msg);
+ }
+ }
+ }
+
+ /**
+ * Add a new syntax error message attributed to the source text between LEFT and RIGHT, and with
+ * message String.format(MESSAGEFORM, ARGS).
+ */
+ public void syntaxError(Location left, Location right, String messageForm, Object... args) {
+ add(new CompilerError(left, right, String.format(messageForm, args), true));
+ }
+
+ /** Add ERR to the list of errors. */
+ public void add(CompilerError err) {
+ errors.add(err);
+ }
+
+ public T dispatch(NodeAnalyzer analyzer) {
+ return analyzer.analyze(this);
+ }
+}
diff --git a/src/main/java/chocopy/common/astnodes/Expr.java b/src/main/java/chocopy/common/astnodes/Expr.java
new file mode 100644
index 0000000..7372d58
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/Expr.java
@@ -0,0 +1,43 @@
+package chocopy.common.astnodes;
+
+import chocopy.common.analysis.types.Type;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+/**
+ * Base of all AST nodes representing expressions.
+ *
+ * There is nothing in this class, but there will be many AST node types that have fields that
+ * are *any expression*. For those cases, having a field of this type will encompass all types of
+ * expressions such as binary expressions and literals that subclass this class.
+ */
+public abstract class Expr extends Node {
+
+ /** A Python expression spanning source locations [LEFT..RIGHT]. */
+ public Expr(Location left, Location right) {
+ super(left, right);
+ }
+
+ /**
+ * The type of the value that this expression evaluates to.
+ *
+ *
This field is always null after the parsing stage, but is populated by the
+ * typechecker in the semantic analysis stage.
+ *
+ *
After typechecking this field may be null only for expressions that cannot be
+ * assigned a type. In particular, {@link NoneLiteral} expressions will not have a typed
+ * assigned to them.
+ */
+ @JsonInclude(JsonInclude.Include.NON_NULL)
+ private Type inferredType;
+
+ /** Set getInferredType() to TYPE, returning TYPE. */
+ public Type setInferredType(Type type) {
+ inferredType = type;
+ return type;
+ }
+
+ public Type getInferredType() {
+ return inferredType;
+ }
+}
diff --git a/src/main/java/chocopy/common/astnodes/ExprStmt.java b/src/main/java/chocopy/common/astnodes/ExprStmt.java
new file mode 100644
index 0000000..5b921a0
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/ExprStmt.java
@@ -0,0 +1,21 @@
+package chocopy.common.astnodes;
+
+import chocopy.common.analysis.NodeAnalyzer;
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+/** Statements consisting of expressions. */
+public final class ExprStmt extends Stmt {
+
+ /** The expression I evaluate. */
+ public final Expr expr;
+
+ /** The AST for EXPR spanning source locations [LEFT..RIGHT] in a statement context. */
+ public ExprStmt(Location left, Location right, Expr expr) {
+ super(left, right);
+ this.expr = expr;
+ }
+
+ public T dispatch(NodeAnalyzer analyzer) {
+ return analyzer.analyze(this);
+ }
+}
diff --git a/src/main/java/chocopy/common/astnodes/ForStmt.java b/src/main/java/chocopy/common/astnodes/ForStmt.java
new file mode 100644
index 0000000..019b2d8
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/ForStmt.java
@@ -0,0 +1,29 @@
+package chocopy.common.astnodes;
+
+import chocopy.common.analysis.NodeAnalyzer;
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+import java.util.List;
+
+/** For statements. */
+public class ForStmt extends Stmt {
+ /** Control variable. */
+ public final Identifier identifier;
+ /** Source of values of control statement. */
+ public final Expr iterable;
+ /** Repeated statements. */
+ public final List body;
+
+ /** The AST for for IDENTIFIER in ITERABLE: BODY spanning source locations [LEFT..RIGHT]. */
+ public ForStmt(
+ Location left, Location right, Identifier identifier, Expr iterable, List body) {
+ super(left, right);
+ this.identifier = identifier;
+ this.iterable = iterable;
+ this.body = body;
+ }
+
+ public T dispatch(NodeAnalyzer analyzer) {
+ return analyzer.analyze(this);
+ }
+}
diff --git a/src/main/java/chocopy/common/astnodes/FuncDef.java b/src/main/java/chocopy/common/astnodes/FuncDef.java
new file mode 100644
index 0000000..b3ca0f2
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/FuncDef.java
@@ -0,0 +1,50 @@
+package chocopy.common.astnodes;
+
+import chocopy.common.analysis.NodeAnalyzer;
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+import java.util.List;
+
+/** Def statements. */
+public class FuncDef extends Declaration {
+
+ /** Defined name. */
+ public final Identifier name;
+ /** Formal parameters. */
+ public final List params;
+ /** Return type annotation. */
+ public final TypeAnnotation returnType;
+ /** Local-variable,inner-function, global, and nonlocal declarations. */
+ public final List declarations;
+ /** Other statements. */
+ public final List statements;
+
+ /**
+ * The AST for def NAME(PARAMS) -> RETURNTYPE: DECLARATIONS STATEMENTS spanning source locations
+ * [LEFT..RIGHT].
+ */
+ public FuncDef(
+ Location left,
+ Location right,
+ Identifier name,
+ List params,
+ TypeAnnotation returnType,
+ List declarations,
+ List statements) {
+ super(left, right);
+ this.name = name;
+ this.params = params;
+ this.returnType = returnType;
+ this.declarations = declarations;
+ this.statements = statements;
+ }
+
+ public T dispatch(NodeAnalyzer analyzer) {
+ return analyzer.analyze(this);
+ }
+
+ @Override
+ public Identifier getIdentifier() {
+ return this.name;
+ }
+}
diff --git a/src/main/java/chocopy/common/astnodes/GlobalDecl.java b/src/main/java/chocopy/common/astnodes/GlobalDecl.java
new file mode 100644
index 0000000..b347d4d
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/GlobalDecl.java
@@ -0,0 +1,26 @@
+package chocopy.common.astnodes;
+
+import chocopy.common.analysis.NodeAnalyzer;
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+/** Declaration of global variable. */
+public class GlobalDecl extends Declaration {
+
+ /** The declared variable. */
+ public final Identifier variable;
+
+ /** The AST for the declaration global VARIABLE spanning source locations [LEFT..RIGHT]. */
+ public GlobalDecl(Location left, Location right, Identifier variable) {
+ super(left, right);
+ this.variable = variable;
+ }
+
+ public T dispatch(NodeAnalyzer analyzer) {
+ return analyzer.analyze(this);
+ }
+
+ @Override
+ public Identifier getIdentifier() {
+ return this.variable;
+ }
+}
diff --git a/src/main/java/chocopy/common/astnodes/Identifier.java b/src/main/java/chocopy/common/astnodes/Identifier.java
new file mode 100644
index 0000000..7593126
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/Identifier.java
@@ -0,0 +1,24 @@
+package chocopy.common.astnodes;
+
+import chocopy.common.analysis.NodeAnalyzer;
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+/** A simple identifier. */
+public class Identifier extends Expr {
+
+ /** Text of the identifier. */
+ public final String name;
+
+ /**
+ * An AST for the variable, method, or parameter named NAME, spanning source locations
+ * [LEFT..RIGHT].
+ */
+ public Identifier(Location left, Location right, String name) {
+ super(left, right);
+ this.name = name;
+ }
+
+ public T dispatch(NodeAnalyzer analyzer) {
+ return analyzer.analyze(this);
+ }
+}
diff --git a/src/main/java/chocopy/common/astnodes/IfExpr.java b/src/main/java/chocopy/common/astnodes/IfExpr.java
new file mode 100644
index 0000000..3d3d809
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/IfExpr.java
@@ -0,0 +1,26 @@
+package chocopy.common.astnodes;
+
+import chocopy.common.analysis.NodeAnalyzer;
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+/** Conditional expressions. */
+public class IfExpr extends Expr {
+ /** Boolean condition. */
+ public final Expr condition;
+ /** True branch. */
+ public final Expr thenExpr;
+ /** False branch. */
+ public final Expr elseExpr;
+
+ /** The AST for THENEXPR if CONDITION else ELSEEXPR spanning source locations [LEFT..RIGHT]. */
+ public IfExpr(Location left, Location right, Expr condition, Expr thenExpr, Expr elseExpr) {
+ super(left, right);
+ this.condition = condition;
+ this.thenExpr = thenExpr;
+ this.elseExpr = elseExpr;
+ }
+
+ public T dispatch(NodeAnalyzer analyzer) {
+ return analyzer.analyze(this);
+ }
+}
diff --git a/src/main/java/chocopy/common/astnodes/IfStmt.java b/src/main/java/chocopy/common/astnodes/IfStmt.java
new file mode 100644
index 0000000..185b8a1
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/IfStmt.java
@@ -0,0 +1,35 @@
+package chocopy.common.astnodes;
+
+import chocopy.common.analysis.NodeAnalyzer;
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+import java.util.List;
+
+/** Conditional statement. */
+public class IfStmt extends Stmt {
+ /** Test condition. */
+ public final Expr condition;
+ /** "True" branch. */
+ public final List thenBody;
+ /** "False" branch. */
+ public final List elseBody;
+
+ /**
+ * The AST for if CONDITION: THENBODY else: ELSEBODY spanning source locations [LEFT..RIGHT].
+ */
+ public IfStmt(
+ Location left,
+ Location right,
+ Expr condition,
+ List thenBody,
+ List elseBody) {
+ super(left, right);
+ this.condition = condition;
+ this.thenBody = thenBody;
+ this.elseBody = elseBody;
+ }
+
+ public T dispatch(NodeAnalyzer analyzer) {
+ return analyzer.analyze(this);
+ }
+}
diff --git a/src/main/java/chocopy/common/astnodes/IndexExpr.java b/src/main/java/chocopy/common/astnodes/IndexExpr.java
new file mode 100644
index 0000000..ce788fa
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/IndexExpr.java
@@ -0,0 +1,24 @@
+package chocopy.common.astnodes;
+
+import chocopy.common.analysis.NodeAnalyzer;
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+/** List-indexing expression. */
+public class IndexExpr extends Expr {
+
+ /** Indexed list. */
+ public final Expr list;
+ /** Expression for index value. */
+ public final Expr index;
+
+ /** The AST for LIST[INDEX]. spanning source locations [LEFT..RIGHT]. */
+ public IndexExpr(Location left, Location right, Expr list, Expr index) {
+ super(left, right);
+ this.list = list;
+ this.index = index;
+ }
+
+ public T dispatch(NodeAnalyzer analyzer) {
+ return analyzer.analyze(this);
+ }
+}
diff --git a/src/main/java/chocopy/common/astnodes/IntegerLiteral.java b/src/main/java/chocopy/common/astnodes/IntegerLiteral.java
new file mode 100644
index 0000000..f2d165b
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/IntegerLiteral.java
@@ -0,0 +1,21 @@
+package chocopy.common.astnodes;
+
+import chocopy.common.analysis.NodeAnalyzer;
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+/** Integer numerals. */
+public final class IntegerLiteral extends Literal {
+
+ /** Value denoted. */
+ public final int value;
+
+ /** The AST for the literal VALUE, spanning source locations [LEFT..RIGHT]. */
+ public IntegerLiteral(Location left, Location right, int value) {
+ super(left, right);
+ this.value = value;
+ }
+
+ public T dispatch(NodeAnalyzer analyzer) {
+ return analyzer.analyze(this);
+ }
+}
diff --git a/src/main/java/chocopy/common/astnodes/ListExpr.java b/src/main/java/chocopy/common/astnodes/ListExpr.java
new file mode 100644
index 0000000..eab6045
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/ListExpr.java
@@ -0,0 +1,23 @@
+package chocopy.common.astnodes;
+
+import chocopy.common.analysis.NodeAnalyzer;
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+import java.util.List;
+
+/** List displays. */
+public final class ListExpr extends Expr {
+
+ /** List of element expressions. */
+ public final List elements;
+
+ /** The AST for [ ELEMENTS ]. spanning source locations [LEFT..RIGHT]. */
+ public ListExpr(Location left, Location right, List elements) {
+ super(left, right);
+ this.elements = elements;
+ }
+
+ public T dispatch(NodeAnalyzer analyzer) {
+ return analyzer.analyze(this);
+ }
+}
diff --git a/src/main/java/chocopy/common/astnodes/ListType.java b/src/main/java/chocopy/common/astnodes/ListType.java
new file mode 100644
index 0000000..32782ad
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/ListType.java
@@ -0,0 +1,21 @@
+package chocopy.common.astnodes;
+
+import chocopy.common.analysis.NodeAnalyzer;
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+/** Type denotation for a list type. */
+public final class ListType extends TypeAnnotation {
+
+ /** The element of list element. */
+ public final TypeAnnotation elementType;
+
+ /** The AST for the type annotation [ ELEMENTTYPE ]. spanning source locations [LEFT..RIGHT]. */
+ public ListType(Location left, Location right, TypeAnnotation elementType) {
+ super(left, right);
+ this.elementType = elementType;
+ }
+
+ public T dispatch(NodeAnalyzer analyzer) {
+ return analyzer.analyze(this);
+ }
+}
diff --git a/src/main/java/chocopy/common/astnodes/Literal.java b/src/main/java/chocopy/common/astnodes/Literal.java
new file mode 100644
index 0000000..2afd1be
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/Literal.java
@@ -0,0 +1,16 @@
+package chocopy.common.astnodes;
+
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+/**
+ * Base of all the literal nodes.
+ *
+ * There is nothing in this class, but it is useful to isolate expressions that are constant
+ * literals.
+ */
+public abstract class Literal extends Expr {
+ /** A literal spanning source locations [LEFT..RIGHT]. */
+ public Literal(Location left, Location right) {
+ super(left, right);
+ }
+}
diff --git a/src/main/java/chocopy/common/astnodes/MemberExpr.java b/src/main/java/chocopy/common/astnodes/MemberExpr.java
new file mode 100644
index 0000000..a9e0a4f
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/MemberExpr.java
@@ -0,0 +1,24 @@
+package chocopy.common.astnodes;
+
+import chocopy.common.analysis.NodeAnalyzer;
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+/** Attribute accessor. */
+public class MemberExpr extends Expr {
+
+ /** Object selected from. */
+ public final Expr object;
+ /** Name of attribute (instance variable or method). */
+ public final Identifier member;
+
+ /** The AST for OBJECT.MEMBER. spanning source locations [LEFT..RIGHT]. */
+ public MemberExpr(Location left, Location right, Expr object, Identifier member) {
+ super(left, right);
+ this.object = object;
+ this.member = member;
+ }
+
+ public T dispatch(NodeAnalyzer analyzer) {
+ return analyzer.analyze(this);
+ }
+}
diff --git a/src/main/java/chocopy/common/astnodes/MethodCallExpr.java b/src/main/java/chocopy/common/astnodes/MethodCallExpr.java
new file mode 100644
index 0000000..ab3f424
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/MethodCallExpr.java
@@ -0,0 +1,26 @@
+package chocopy.common.astnodes;
+
+import chocopy.common.analysis.NodeAnalyzer;
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+import java.util.List;
+
+/** Method calls. */
+public class MethodCallExpr extends Expr {
+
+ /** Expression for the bound method to be called. */
+ public final MemberExpr method;
+ /** Actual parameters. */
+ public final List args;
+
+ /** The AST for METHOD(ARGS). spanning source locations [LEFT..RIGHT]. */
+ public MethodCallExpr(Location left, Location right, MemberExpr method, List args) {
+ super(left, right);
+ this.method = method;
+ this.args = args;
+ }
+
+ public T dispatch(NodeAnalyzer analyzer) {
+ return analyzer.analyze(this);
+ }
+}
diff --git a/src/main/java/chocopy/common/astnodes/Node.java b/src/main/java/chocopy/common/astnodes/Node.java
new file mode 100644
index 0000000..c95f3d6
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/Node.java
@@ -0,0 +1,176 @@
+package chocopy.common.astnodes;
+
+import chocopy.common.analysis.NodeAnalyzer;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonSubTypes;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+import java.io.IOException;
+
+/**
+ * Root of the AST class hierarchy. Every node has a left and right location, indicating the start
+ * and end of the represented construct in the source text.
+ *
+ * Every node can be marked with an error message, which serves two purposes: 1. It indicates
+ * that an error message has been issued for this Node, allowing tne program to reduce cascades of
+ * error messages. 2. It aids in debugging by making it convenient to see which Nodes have caused an
+ * error.
+ */
+@JsonTypeInfo(
+ use = JsonTypeInfo.Id.NAME,
+ include = JsonTypeInfo.As.EXISTING_PROPERTY,
+ property = "kind")
+/* List of all concrete subclasses of Node. */
+@JsonSubTypes({
+ @JsonSubTypes.Type(AssignStmt.class),
+ @JsonSubTypes.Type(BinaryExpr.class),
+ @JsonSubTypes.Type(BooleanLiteral.class),
+ @JsonSubTypes.Type(CallExpr.class),
+ @JsonSubTypes.Type(ClassDef.class),
+ @JsonSubTypes.Type(ClassType.class),
+ @JsonSubTypes.Type(CompilerError.class),
+ @JsonSubTypes.Type(Errors.class),
+ @JsonSubTypes.Type(ExprStmt.class),
+ @JsonSubTypes.Type(ForStmt.class),
+ @JsonSubTypes.Type(FuncDef.class),
+ @JsonSubTypes.Type(GlobalDecl.class),
+ @JsonSubTypes.Type(Identifier.class),
+ @JsonSubTypes.Type(IfExpr.class),
+ @JsonSubTypes.Type(IfStmt.class),
+ @JsonSubTypes.Type(IndexExpr.class),
+ @JsonSubTypes.Type(IntegerLiteral.class),
+ @JsonSubTypes.Type(ListExpr.class),
+ @JsonSubTypes.Type(ListType.class),
+ @JsonSubTypes.Type(MemberExpr.class),
+ @JsonSubTypes.Type(MethodCallExpr.class),
+ @JsonSubTypes.Type(NoneLiteral.class),
+ @JsonSubTypes.Type(NonLocalDecl.class),
+ @JsonSubTypes.Type(Program.class),
+ @JsonSubTypes.Type(ReturnStmt.class),
+ @JsonSubTypes.Type(StringLiteral.class),
+ @JsonSubTypes.Type(TypedVar.class),
+ @JsonSubTypes.Type(UnaryExpr.class),
+ @JsonSubTypes.Type(VarDef.class),
+ @JsonSubTypes.Type(WhileStmt.class),
+})
+public abstract class Node {
+
+ /** Node-type indicator for JSON form. */
+ public final String kind;
+
+ /**
+ * Source position information: 0: line number of start, 1: column number of start, 2: line
+ * number of end, 3: column number of end.
+ */
+ private final int[] location = new int[4];
+
+ /**
+ * First error message "blamed" on this Node. When non-null, indicates that an error has been
+ * found in this Node.
+ */
+ @JsonInclude(JsonInclude.Include.NON_EMPTY)
+ private String errorMsg;
+
+ /** A Node corresponding to source text between LEFT and RIGHT. */
+ public Node(Location left, Location right) {
+ if (left != null) {
+ location[0] = left.getLine();
+ location[1] = left.getColumn();
+ }
+ if (right != null) {
+ location[2] = right.getLine();
+ location[3] = right.getColumn();
+ }
+ this.kind = getClass().getSimpleName();
+ this.errorMsg = null;
+ }
+
+ /**
+ * Return my source location as { , , , }.
+ * Result should not be modified, and contents will change after setLocation().
+ */
+ public int[] getLocation() {
+ return location;
+ }
+
+ /** Copy LOCATION as getLocation(). */
+ public void setLocation(final int[] location) {
+ System.arraycopy(location, 0, this.location, 0, 4);
+ }
+
+ public String getErrorMsg() {
+ return errorMsg;
+ }
+
+ public void setErrorMsg(String msg) {
+ this.errorMsg = msg;
+ }
+
+ /** Return true iff I have been marked with an error message. */
+ @JsonIgnore
+ public boolean hasError() {
+ return this.errorMsg != null;
+ }
+
+ /**
+ * Invoke ANALYZER on me as a node of static type T. See the comment on NodeAnalyzer. Returns
+ * modified Node.
+ */
+ public abstract T dispatch(NodeAnalyzer analyzer);
+
+ /** Print out the AST in JSON format. */
+ @Override
+ public String toString() {
+ try {
+ return toJSON();
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /** Return a serialization of this node in JSON format. */
+ public String toJSON() throws JsonProcessingException {
+ return mapper.writeValueAsString(this);
+ }
+
+ /** Mapper to-and-from serialized JSON. */
+ private static final ObjectMapper mapper = new ObjectMapper();
+
+ static {
+ mapper.enable(SerializationFeature.INDENT_OUTPUT);
+ mapper.registerModule(new ParameterNamesModule());
+ }
+
+ /** Returns a T from JSON, a JSON-serialized T value with class CLAS. */
+ public static T fromJSON(String json, Class clas) throws IOException {
+ return mapper.readValue(json, clas);
+ }
+
+ /**
+ * Returns the result of converting JSON, a JSon-serialization of a Node value, into the value
+ * it serializes.
+ */
+ public static Node fromJSON(String json) throws IOException {
+ return fromJSON(json, Node.class);
+ }
+
+ /**
+ * Returns the result of converting TREE to the value of type T that it represents, where CLAS
+ * reflects T.
+ */
+ public static T fromJSON(JsonNode tree, Class clas) throws IOException {
+ return mapper.treeToValue(tree, clas);
+ }
+
+ /** Returns the translation of serialized value SRC into the corresponding JSON tree. */
+ public static JsonNode readTree(String src) throws IOException {
+ return mapper.readTree(src);
+ }
+}
diff --git a/src/main/java/chocopy/common/astnodes/NonLocalDecl.java b/src/main/java/chocopy/common/astnodes/NonLocalDecl.java
new file mode 100644
index 0000000..ebaf78d
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/NonLocalDecl.java
@@ -0,0 +1,26 @@
+package chocopy.common.astnodes;
+
+import chocopy.common.analysis.NodeAnalyzer;
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+/** Nonlocal declaration. */
+public class NonLocalDecl extends Declaration {
+
+ /** Name of identifier being declared. */
+ public final Identifier variable;
+
+ /** The AST for nonlocal VARIABLE spanning source locations [LEFT..RIGHT]. */
+ public NonLocalDecl(Location left, Location right, Identifier variable) {
+ super(left, right);
+ this.variable = variable;
+ }
+
+ public T dispatch(NodeAnalyzer analyzer) {
+ return analyzer.analyze(this);
+ }
+
+ @Override
+ public Identifier getIdentifier() {
+ return this.variable;
+ }
+}
diff --git a/src/main/java/chocopy/common/astnodes/NoneLiteral.java b/src/main/java/chocopy/common/astnodes/NoneLiteral.java
new file mode 100644
index 0000000..b51a581
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/NoneLiteral.java
@@ -0,0 +1,17 @@
+package chocopy.common.astnodes;
+
+import chocopy.common.analysis.NodeAnalyzer;
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+/** The expression 'None'. */
+public final class NoneLiteral extends Literal {
+
+ /** The AST for None, spanning source locations [LEFT..RIGHT]. */
+ public NoneLiteral(Location left, Location right) {
+ super(left, right);
+ }
+
+ public T dispatch(NodeAnalyzer analyzer) {
+ return analyzer.analyze(this);
+ }
+}
diff --git a/src/main/java/chocopy/common/astnodes/Program.java b/src/main/java/chocopy/common/astnodes/Program.java
new file mode 100644
index 0000000..e95b2e7
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/Program.java
@@ -0,0 +1,56 @@
+package chocopy.common.astnodes;
+
+import chocopy.common.analysis.NodeAnalyzer;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/** An entire Chocopy program. */
+public class Program extends Node {
+
+ /** Initial variable, class, and function declarations. */
+ public final List declarations;
+ /** Trailing statements. */
+ public final List statements;
+ /** Accumulated errors. */
+ public final Errors errors;
+
+ /**
+ * The AST for the program DECLARATIONS STATEMENTS spanning source locations [LEFT..RIGHT].
+ *
+ * ERRORS is the container for all error messages applying to the program.
+ */
+ public Program(
+ Location left,
+ Location right,
+ List declarations,
+ List statements,
+ Errors errors) {
+ super(left, right);
+ this.declarations = declarations;
+ this.statements = statements;
+ if (errors == null) {
+ this.errors = new Errors(new ArrayList<>());
+ } else {
+ this.errors = errors;
+ }
+ }
+
+ public T dispatch(NodeAnalyzer analyzer) {
+ return analyzer.analyze(this);
+ }
+
+ /** Returns true iff there is at least one error in the program. */
+ @JsonIgnore
+ public boolean hasErrors() {
+ return errors.hasErrors();
+ }
+
+ /** A convenience method returning the list of all CompilerErrors for this program. */
+ @JsonIgnore
+ public List getErrorList() {
+ return errors.errors;
+ }
+}
diff --git a/src/main/java/chocopy/common/astnodes/ReturnStmt.java b/src/main/java/chocopy/common/astnodes/ReturnStmt.java
new file mode 100644
index 0000000..e665042
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/ReturnStmt.java
@@ -0,0 +1,21 @@
+package chocopy.common.astnodes;
+
+import chocopy.common.analysis.NodeAnalyzer;
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+/** Return from function. */
+public class ReturnStmt extends Stmt {
+
+ /** Returned value. */
+ public final Expr value;
+
+ /** The AST for return VALUE spanning source locations [LEFT..RIGHT]. */
+ public ReturnStmt(Location left, Location right, Expr value) {
+ super(left, right);
+ this.value = value;
+ }
+
+ public T dispatch(NodeAnalyzer analyzer) {
+ return analyzer.analyze(this);
+ }
+}
diff --git a/src/main/java/chocopy/common/astnodes/Stmt.java b/src/main/java/chocopy/common/astnodes/Stmt.java
new file mode 100644
index 0000000..b87780e
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/Stmt.java
@@ -0,0 +1,18 @@
+package chocopy.common.astnodes;
+
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+/**
+ * Base of all AST nodes representing statements.
+ *
+ * There is nothing in this class, but there will be some AST node types that have fields that
+ * are *any statement* or a list of statements. For those cases, having a field of this type will
+ * encompass all types of statements such as expression statements, if statements, while statements,
+ * etc.
+ */
+public abstract class Stmt extends Node {
+ /** A statement spanning source locations [LEFT..RIGHT]. */
+ public Stmt(Location left, Location right) {
+ super(left, right);
+ }
+}
diff --git a/src/main/java/chocopy/common/astnodes/StringLiteral.java b/src/main/java/chocopy/common/astnodes/StringLiteral.java
new file mode 100644
index 0000000..0eaf928
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/StringLiteral.java
@@ -0,0 +1,21 @@
+package chocopy.common.astnodes;
+
+import chocopy.common.analysis.NodeAnalyzer;
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+/** String constants. */
+public final class StringLiteral extends Literal {
+
+ /** Contents of the literal, not including quotation marks. */
+ public final String value;
+
+ /** The AST for a string literal containing VALUE, spanning source locations [LEFT..RIGHT]. */
+ public StringLiteral(Location left, Location right, String value) {
+ super(left, right);
+ this.value = value;
+ }
+
+ public T dispatch(NodeAnalyzer analyzer) {
+ return analyzer.analyze(this);
+ }
+}
diff --git a/src/main/java/chocopy/common/astnodes/TypeAnnotation.java b/src/main/java/chocopy/common/astnodes/TypeAnnotation.java
new file mode 100644
index 0000000..d90b59e
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/TypeAnnotation.java
@@ -0,0 +1,11 @@
+package chocopy.common.astnodes;
+
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+/** Base of all AST nodes representing type annotations (list or class types. */
+public abstract class TypeAnnotation extends Node {
+ /** An annotation spanning source locations [LEFT..RIGHT]. */
+ public TypeAnnotation(Location left, Location right) {
+ super(left, right);
+ }
+}
diff --git a/src/main/java/chocopy/common/astnodes/TypedVar.java b/src/main/java/chocopy/common/astnodes/TypedVar.java
new file mode 100644
index 0000000..98aae43
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/TypedVar.java
@@ -0,0 +1,24 @@
+package chocopy.common.astnodes;
+
+import chocopy.common.analysis.NodeAnalyzer;
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+/** An identifier with attached type annotation. */
+public class TypedVar extends Node {
+
+ /** The typed identifier. */
+ public final Identifier identifier;
+ /** The declared type. */
+ public final TypeAnnotation type;
+
+ /** The AST for IDENTIFIER : TYPE. spanning source locations [LEFT..RIGHT]. */
+ public TypedVar(Location left, Location right, Identifier identifier, TypeAnnotation type) {
+ super(left, right);
+ this.identifier = identifier;
+ this.type = type;
+ }
+
+ public T dispatch(NodeAnalyzer analyzer) {
+ return analyzer.analyze(this);
+ }
+}
diff --git a/src/main/java/chocopy/common/astnodes/UnaryExpr.java b/src/main/java/chocopy/common/astnodes/UnaryExpr.java
new file mode 100644
index 0000000..199e701
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/UnaryExpr.java
@@ -0,0 +1,24 @@
+package chocopy.common.astnodes;
+
+import chocopy.common.analysis.NodeAnalyzer;
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+/** An expression applying a unary operator. */
+public class UnaryExpr extends Expr {
+
+ /** The text representation of the operator. */
+ public final String operator;
+ /** The operand to which it is applied. */
+ public final Expr operand;
+
+ /** The AST for OPERATOR OPERAND spanning source locations [LEFT..RIGHT]. */
+ public UnaryExpr(Location left, Location right, String operator, Expr operand) {
+ super(left, right);
+ this.operator = operator;
+ this.operand = operand;
+ }
+
+ public T dispatch(NodeAnalyzer analyzer) {
+ return analyzer.analyze(this);
+ }
+}
diff --git a/src/main/java/chocopy/common/astnodes/VarDef.java b/src/main/java/chocopy/common/astnodes/VarDef.java
new file mode 100644
index 0000000..61d261a
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/VarDef.java
@@ -0,0 +1,32 @@
+package chocopy.common.astnodes;
+
+import chocopy.common.analysis.NodeAnalyzer;
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+/** A declaration of a variable (i.e., with type annotation). */
+public class VarDef extends Declaration {
+ /** The variable and its assigned type. */
+ public final TypedVar var;
+ /** The initial value assigned. */
+ public final Literal value;
+
+ /**
+ * The AST for VAR = VALUE where VAR has a type annotation, and spanning source locations
+ * [LEFT..RIGHT].
+ */
+ public VarDef(Location left, Location right, TypedVar var, Literal value) {
+ super(left, right);
+ this.var = var;
+ this.value = value;
+ }
+
+ public T dispatch(NodeAnalyzer analyzer) {
+ return analyzer.analyze(this);
+ }
+
+ /** The identifier defined by this declaration. */
+ @Override
+ public Identifier getIdentifier() {
+ return this.var.identifier;
+ }
+}
diff --git a/src/main/java/chocopy/common/astnodes/WhileStmt.java b/src/main/java/chocopy/common/astnodes/WhileStmt.java
new file mode 100644
index 0000000..9a521e1
--- /dev/null
+++ b/src/main/java/chocopy/common/astnodes/WhileStmt.java
@@ -0,0 +1,25 @@
+package chocopy.common.astnodes;
+
+import chocopy.common.analysis.NodeAnalyzer;
+import java_cup.runtime.ComplexSymbolFactory.Location;
+
+import java.util.List;
+
+/** Indefinite repetition construct. */
+public class WhileStmt extends Stmt {
+ /** Test for whether to continue. */
+ public final Expr condition;
+ /** Loop body. */
+ public final List body;
+
+ /** The AST for while CONDITION: BODY spanning source locations [LEFT..RIGHT]. */
+ public WhileStmt(Location left, Location right, Expr condition, List body) {
+ super(left, right);
+ this.condition = condition;
+ this.body = body;
+ }
+
+ public T dispatch(NodeAnalyzer analyzer) {
+ return analyzer.analyze(this);
+ }
+}
diff --git a/src/main/java/chocopy/pa2/DeclarationAnalyzer.java b/src/main/java/chocopy/pa2/DeclarationAnalyzer.java
new file mode 100644
index 0000000..29aaf5a
--- /dev/null
+++ b/src/main/java/chocopy/pa2/DeclarationAnalyzer.java
@@ -0,0 +1,55 @@
+package chocopy.pa2;
+
+import chocopy.common.analysis.AbstractNodeAnalyzer;
+import chocopy.common.analysis.SymbolTable;
+import chocopy.common.analysis.types.Type;
+import chocopy.common.analysis.types.ValueType;
+import chocopy.common.astnodes.*;
+
+/** Analyzes declarations to create a top-level symbol table. */
+public class DeclarationAnalyzer extends AbstractNodeAnalyzer {
+
+ /** Current symbol table. Changes with new declarative region. */
+ private final SymbolTable sym = new SymbolTable<>();
+ /** Global symbol table. */
+ private final SymbolTable globals = sym;
+ /** Receiver for semantic error messages. */
+ private final Errors errors;
+
+ /** A new declaration analyzer sending errors to ERRORS0. */
+ public DeclarationAnalyzer(Errors errors0) {
+ errors = errors0;
+ }
+
+ public SymbolTable getGlobals() {
+ return globals;
+ }
+
+ @Override
+ public Type analyze(Program program) {
+ for (Declaration decl : program.declarations) {
+ Identifier id = decl.getIdentifier();
+ String name = id.name;
+
+ Type type = decl.dispatch(this);
+
+ if (type == null) {
+ continue;
+ }
+
+ if (sym.declares(name)) {
+ errors.semError(
+ id, "Duplicate declaration of identifier in same " + "scope: %s", name);
+ } else {
+ sym.put(name, type);
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public Type analyze(VarDef varDef) {
+ return ValueType.annotationToValueType(varDef.var.type);
+ }
+}
diff --git a/src/main/java/chocopy/pa2/StudentAnalysis.java b/src/main/java/chocopy/pa2/StudentAnalysis.java
new file mode 100644
index 0000000..b008a2b
--- /dev/null
+++ b/src/main/java/chocopy/pa2/StudentAnalysis.java
@@ -0,0 +1,30 @@
+package chocopy.pa2;
+
+import chocopy.common.analysis.SymbolTable;
+import chocopy.common.analysis.types.Type;
+import chocopy.common.astnodes.Program;
+
+/** Top-level class for performing semantic analysis. */
+public class StudentAnalysis {
+
+ /**
+ * Perform semantic analysis on PROGRAM, adding error messages and type annotations. Provide
+ * debugging output iff DEBUG. Returns modified tree.
+ */
+ public static Program process(Program program, boolean debug) {
+ if (program.hasErrors()) {
+ return program;
+ }
+
+ DeclarationAnalyzer declarationAnalyzer = new DeclarationAnalyzer(program.errors);
+ program.dispatch(declarationAnalyzer);
+ SymbolTable globalSym = declarationAnalyzer.getGlobals();
+
+ if (!program.hasErrors()) {
+ TypeChecker typeChecker = new TypeChecker(globalSym, program.errors);
+ program.dispatch(typeChecker);
+ }
+
+ return program;
+ }
+}
diff --git a/src/main/java/chocopy/pa2/TypeChecker.java b/src/main/java/chocopy/pa2/TypeChecker.java
new file mode 100644
index 0000000..ab8acc1
--- /dev/null
+++ b/src/main/java/chocopy/pa2/TypeChecker.java
@@ -0,0 +1,94 @@
+package chocopy.pa2;
+
+import chocopy.common.analysis.AbstractNodeAnalyzer;
+import chocopy.common.analysis.SymbolTable;
+import chocopy.common.analysis.types.Type;
+import chocopy.common.analysis.types.ValueType;
+import chocopy.common.astnodes.*;
+
+import static chocopy.common.analysis.types.Type.INT_TYPE;
+import static chocopy.common.analysis.types.Type.OBJECT_TYPE;
+
+/**
+ * Analyzer that performs ChocoPy type checks on all nodes. Applied after collecting declarations.
+ */
+public class TypeChecker extends AbstractNodeAnalyzer {
+
+ /** The current symbol table (changes depending on the function being analyzed). */
+ private final SymbolTable sym;
+ /** Collector for errors. */
+ private final Errors errors;
+
+ /**
+ * Creates a type checker using GLOBALSYMBOLS for the initial global symbol table and ERRORS0 to
+ * receive semantic errors.
+ */
+ public TypeChecker(SymbolTable globalSymbols, Errors errors0) {
+ sym = globalSymbols;
+ errors = errors0;
+ }
+
+ /**
+ * Inserts an error message in NODE if there isn't one already. The message is constructed with
+ * MESSAGE and ARGS as for String.format.
+ */
+ private void err(Node node, String message, Object... args) {
+ errors.semError(node, message, args);
+ }
+
+ @Override
+ public Type analyze(Program program) {
+ for (Declaration decl : program.declarations) {
+ decl.dispatch(this);
+ }
+ for (Stmt stmt : program.statements) {
+ stmt.dispatch(this);
+ }
+ return null;
+ }
+
+ @Override
+ public Type analyze(ExprStmt s) {
+ s.expr.dispatch(this);
+ return null;
+ }
+
+ @Override
+ public Type analyze(IntegerLiteral i) {
+ return i.setInferredType(Type.INT_TYPE);
+ }
+
+ @Override
+ public Type analyze(BinaryExpr e) {
+ Type t1 = e.left.dispatch(this);
+ Type t2 = e.right.dispatch(this);
+
+ switch (e.operator) {
+ case "-":
+ case "*":
+ case "//":
+ case "%":
+ if (INT_TYPE.equals(t1) && INT_TYPE.equals(t2)) {
+ return e.setInferredType(INT_TYPE);
+ } else {
+ err(e, "Cannot apply operator `%s` on types `%s` and `%s`", e.operator, t1, t2);
+ return e.setInferredType(INT_TYPE);
+ }
+ default:
+ return e.setInferredType(OBJECT_TYPE);
+ }
+ }
+
+ @Override
+ public Type analyze(Identifier id) {
+ String varName = id.name;
+ Type varType = sym.get(varName);
+
+ if (varType != null && varType.isValueType()) {
+ return id.setInferredType(varType);
+ }
+
+ err(id, "Not a variable: %s", varName);
+ return id.setInferredType(ValueType.OBJECT_TYPE);
+ }
+}
diff --git a/src/test/data/pa2/sample/ast_coverage.py b/src/test/data/pa2/sample/ast_coverage.py
new file mode 100644
index 0000000..a27e796
--- /dev/null
+++ b/src/test/data/pa2/sample/ast_coverage.py
@@ -0,0 +1,38 @@
+count:int = 0
+
+def foo(s: str) -> int:
+ return len(s)
+
+class bar(object):
+ p: bool = True
+
+ def baz(self:"bar", xx: [int]) -> str:
+ global count
+ x:int = 0
+ y:int = 1
+
+ def qux(y: int) -> object:
+ nonlocal x
+ if x > y:
+ x = -1
+
+ for x in xx:
+ self.p = x == 2
+
+ qux(0) # Yay! ChocoPy
+
+ count = count + 1
+
+ while x <= 0:
+ if self.p:
+ xx[0] = xx[1]
+ self.p = not self.p
+ x = x + 1
+ elif foo("Long"[0]) == 1:
+ self.p = self is None
+
+ return "Nope"
+
+print(bar().baz([1,2]))
+
+
diff --git a/src/test/data/pa2/sample/ast_coverage.py.ast b/src/test/data/pa2/sample/ast_coverage.py.ast
new file mode 100644
index 0000000..18d47cd
--- /dev/null
+++ b/src/test/data/pa2/sample/ast_coverage.py.ast
@@ -0,0 +1,627 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 36, 24 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 5 ],
+ "name" : "count"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 7, 1, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 13, 1, 13 ],
+ "value" : 0
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 3, 1, 4, 18 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 5, 3, 7 ],
+ "name" : "foo"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 3, 9, 3, 14 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 9, 3, 9 ],
+ "name" : "s"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 3, 12, 3, 14 ],
+ "className" : "str"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 3, 20, 3, 22 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 4, 5, 4, 17 ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 4, 12, 4, 17 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 12, 4, 14 ],
+ "name" : "len"
+ },
+ "args" : [ {
+ "kind" : "Identifier",
+ "location" : [ 4, 16, 4, 16 ],
+ "name" : "s"
+ } ]
+ }
+ } ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 6, 1, 36, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 6, 7, 6, 9 ],
+ "name" : "bar"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 6, 11, 6, 16 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 7, 5, 7, 18 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 7, 5, 7, 11 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 5, 7, 5 ],
+ "name" : "p"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 7, 8, 7, 11 ],
+ "className" : "bool"
+ }
+ },
+ "value" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 7, 15, 7, 18 ],
+ "value" : true
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 9, 5, 34, 22 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 9, 9, 11 ],
+ "name" : "baz"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 9, 13, 9, 22 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 13, 9, 16 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 9, 18, 9, 22 ],
+ "className" : "bar"
+ }
+ }, {
+ "kind" : "TypedVar",
+ "location" : [ 9, 25, 9, 33 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 25, 9, 26 ],
+ "name" : "xx"
+ },
+ "type" : {
+ "kind" : "ListType",
+ "location" : [ 9, 29, 9, 33 ],
+ "elementType" : {
+ "kind" : "ClassType",
+ "location" : [ 9, 30, 9, 32 ],
+ "className" : "int"
+ }
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 9, 39, 9, 41 ],
+ "className" : "str"
+ },
+ "declarations" : [ {
+ "kind" : "GlobalDecl",
+ "location" : [ 10, 9, 10, 20 ],
+ "variable" : {
+ "kind" : "Identifier",
+ "location" : [ 10, 16, 10, 20 ],
+ "name" : "count"
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 11, 9, 11, 17 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 11, 9, 11, 13 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 9, 11, 9 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 11, 11, 11, 13 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 11, 17, 11, 17 ],
+ "value" : 0
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 12, 9, 12, 17 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 12, 9, 12, 13 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 12, 9, 12, 9 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 12, 11, 12, 13 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 12, 17, 12, 17 ],
+ "value" : 1
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 14, 9, 19, 8 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 14, 13, 14, 15 ],
+ "name" : "qux"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 14, 17, 14, 22 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 14, 17, 14, 17 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 14, 20, 14, 22 ],
+ "className" : "int"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 14, 28, 14, 33 ],
+ "className" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "NonLocalDecl",
+ "location" : [ 15, 13, 15, 22 ],
+ "variable" : {
+ "kind" : "Identifier",
+ "location" : [ 15, 22, 15, 22 ],
+ "name" : "x"
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "IfStmt",
+ "location" : [ 16, 13, 19, 8 ],
+ "condition" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 16, 16, 16, 20 ],
+ "left" : {
+ "kind" : "Identifier",
+ "location" : [ 16, 16, 16, 16 ],
+ "name" : "x"
+ },
+ "operator" : ">",
+ "right" : {
+ "kind" : "Identifier",
+ "location" : [ 16, 20, 16, 20 ],
+ "name" : "y"
+ }
+ },
+ "thenBody" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 17, 17, 17, 22 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 17, 17, 17, 17 ],
+ "name" : "x"
+ } ],
+ "value" : {
+ "kind" : "UnaryExpr",
+ "location" : [ 17, 21, 17, 22 ],
+ "operator" : "-",
+ "operand" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 17, 22, 17, 22 ],
+ "value" : 1
+ }
+ }
+ } ],
+ "elseBody" : [ ]
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ForStmt",
+ "location" : [ 19, 9, 22, 8 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 19, 13, 19, 13 ],
+ "name" : "x"
+ },
+ "iterable" : {
+ "kind" : "Identifier",
+ "location" : [ 19, 18, 19, 19 ],
+ "name" : "xx"
+ },
+ "body" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 20, 13, 20, 27 ],
+ "targets" : [ {
+ "kind" : "MemberExpr",
+ "location" : [ 20, 13, 20, 18 ],
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 20, 13, 20, 16 ],
+ "name" : "self"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 20, 18, 20, 18 ],
+ "name" : "p"
+ }
+ } ],
+ "value" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 20, 22, 20, 27 ],
+ "left" : {
+ "kind" : "Identifier",
+ "location" : [ 20, 22, 20, 22 ],
+ "name" : "x"
+ },
+ "operator" : "==",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 20, 27, 20, 27 ],
+ "value" : 2
+ }
+ }
+ } ]
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 22, 9, 22, 14 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 22, 9, 22, 14 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 22, 9, 22, 11 ],
+ "name" : "qux"
+ },
+ "args" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 22, 13, 22, 13 ],
+ "value" : 0
+ } ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 24, 9, 24, 25 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 24, 9, 24, 13 ],
+ "name" : "count"
+ } ],
+ "value" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 24, 17, 24, 25 ],
+ "left" : {
+ "kind" : "Identifier",
+ "location" : [ 24, 17, 24, 21 ],
+ "name" : "count"
+ },
+ "operator" : "+",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 24, 25, 24, 25 ],
+ "value" : 1
+ }
+ }
+ }, {
+ "kind" : "WhileStmt",
+ "location" : [ 26, 9, 34, 8 ],
+ "condition" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 26, 15, 26, 20 ],
+ "left" : {
+ "kind" : "Identifier",
+ "location" : [ 26, 15, 26, 15 ],
+ "name" : "x"
+ },
+ "operator" : "<=",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 26, 20, 26, 20 ],
+ "value" : 0
+ }
+ },
+ "body" : [ {
+ "kind" : "IfStmt",
+ "location" : [ 27, 13, 34, 8 ],
+ "condition" : {
+ "kind" : "MemberExpr",
+ "location" : [ 27, 16, 27, 21 ],
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 27, 16, 27, 19 ],
+ "name" : "self"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 27, 21, 27, 21 ],
+ "name" : "p"
+ }
+ },
+ "thenBody" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 28, 17, 28, 29 ],
+ "targets" : [ {
+ "kind" : "IndexExpr",
+ "location" : [ 28, 17, 28, 21 ],
+ "list" : {
+ "kind" : "Identifier",
+ "location" : [ 28, 17, 28, 18 ],
+ "name" : "xx"
+ },
+ "index" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 28, 20, 28, 20 ],
+ "value" : 0
+ }
+ } ],
+ "value" : {
+ "kind" : "IndexExpr",
+ "location" : [ 28, 25, 28, 29 ],
+ "list" : {
+ "kind" : "Identifier",
+ "location" : [ 28, 25, 28, 26 ],
+ "name" : "xx"
+ },
+ "index" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 28, 28, 28, 28 ],
+ "value" : 1
+ }
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 29, 17, 29, 35 ],
+ "targets" : [ {
+ "kind" : "MemberExpr",
+ "location" : [ 29, 17, 29, 22 ],
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 29, 17, 29, 20 ],
+ "name" : "self"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 29, 22, 29, 22 ],
+ "name" : "p"
+ }
+ } ],
+ "value" : {
+ "kind" : "UnaryExpr",
+ "location" : [ 29, 26, 29, 35 ],
+ "operator" : "not",
+ "operand" : {
+ "kind" : "MemberExpr",
+ "location" : [ 29, 30, 29, 35 ],
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 29, 30, 29, 33 ],
+ "name" : "self"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 29, 35, 29, 35 ],
+ "name" : "p"
+ }
+ }
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 30, 17, 30, 25 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 30, 17, 30, 17 ],
+ "name" : "x"
+ } ],
+ "value" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 30, 21, 30, 25 ],
+ "left" : {
+ "kind" : "Identifier",
+ "location" : [ 30, 21, 30, 21 ],
+ "name" : "x"
+ },
+ "operator" : "+",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 30, 25, 30, 25 ],
+ "value" : 1
+ }
+ }
+ } ],
+ "elseBody" : [ {
+ "kind" : "IfStmt",
+ "location" : [ 31, 13, 34, 8 ],
+ "condition" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 31, 18, 31, 36 ],
+ "left" : {
+ "kind" : "CallExpr",
+ "location" : [ 31, 18, 31, 31 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 31, 18, 31, 20 ],
+ "name" : "foo"
+ },
+ "args" : [ {
+ "kind" : "IndexExpr",
+ "location" : [ 31, 22, 31, 30 ],
+ "list" : {
+ "kind" : "StringLiteral",
+ "location" : [ 31, 22, 31, 27 ],
+ "value" : "Long"
+ },
+ "index" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 31, 29, 31, 29 ],
+ "value" : 0
+ }
+ } ]
+ },
+ "operator" : "==",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 31, 36, 31, 36 ],
+ "value" : 1
+ }
+ },
+ "thenBody" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 32, 17, 32, 37 ],
+ "targets" : [ {
+ "kind" : "MemberExpr",
+ "location" : [ 32, 17, 32, 22 ],
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 32, 17, 32, 20 ],
+ "name" : "self"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 32, 22, 32, 22 ],
+ "name" : "p"
+ }
+ } ],
+ "value" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 32, 26, 32, 37 ],
+ "left" : {
+ "kind" : "Identifier",
+ "location" : [ 32, 26, 32, 29 ],
+ "name" : "self"
+ },
+ "operator" : "is",
+ "right" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 32, 34, 32, 37 ]
+ }
+ }
+ } ],
+ "elseBody" : [ ]
+ } ]
+ } ]
+ }, {
+ "kind" : "ReturnStmt",
+ "location" : [ 34, 9, 34, 21 ],
+ "value" : {
+ "kind" : "StringLiteral",
+ "location" : [ 34, 16, 34, 21 ],
+ "value" : "Nope"
+ }
+ } ]
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 36, 1, 36, 23 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 36, 1, 36, 23 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 36, 1, 36, 5 ],
+ "name" : "print"
+ },
+ "args" : [ {
+ "kind" : "MethodCallExpr",
+ "location" : [ 36, 7, 36, 22 ],
+ "method" : {
+ "kind" : "MemberExpr",
+ "location" : [ 36, 7, 36, 15 ],
+ "object" : {
+ "kind" : "CallExpr",
+ "location" : [ 36, 7, 36, 11 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 36, 7, 36, 9 ],
+ "name" : "bar"
+ },
+ "args" : [ ]
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 36, 13, 36, 15 ],
+ "name" : "baz"
+ }
+ },
+ "args" : [ {
+ "kind" : "ListExpr",
+ "location" : [ 36, 17, 36, 21 ],
+ "elements" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 36, 18, 36, 18 ],
+ "value" : 1
+ }, {
+ "kind" : "IntegerLiteral",
+ "location" : [ 36, 20, 36, 20 ],
+ "value" : 2
+ } ]
+ } ]
+ } ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/ast_coverage.py.ast.typed b/src/test/data/pa2/sample/ast_coverage.py.ast.typed
new file mode 100644
index 0000000..709f895
--- /dev/null
+++ b/src/test/data/pa2/sample/ast_coverage.py.ast.typed
@@ -0,0 +1,952 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 36, 24 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 5 ],
+ "name" : "count"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 7, 1, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 13, 1, 13 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 0
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 3, 1, 4, 18 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 5, 3, 7 ],
+ "name" : "foo"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 3, 9, 3, 14 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 9, 3, 9 ],
+ "name" : "s"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 3, 12, 3, 14 ],
+ "className" : "str"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 3, 20, 3, 22 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 4, 5, 4, 17 ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 4, 12, 4, 17 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 12, 4, 14 ],
+ "inferredType" : {
+ "kind" : "FuncType",
+ "parameters" : [ {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ } ],
+ "returnType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "name" : "len"
+ },
+ "args" : [ {
+ "kind" : "Identifier",
+ "location" : [ 4, 16, 4, 16 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "name" : "s"
+ } ]
+ }
+ } ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 6, 1, 36, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 6, 7, 6, 9 ],
+ "name" : "bar"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 6, 11, 6, 16 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 7, 5, 7, 18 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 7, 5, 7, 11 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 5, 7, 5 ],
+ "name" : "p"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 7, 8, 7, 11 ],
+ "className" : "bool"
+ }
+ },
+ "value" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 7, 15, 7, 18 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : true
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 9, 5, 34, 22 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 9, 9, 11 ],
+ "name" : "baz"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 9, 13, 9, 22 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 13, 9, 16 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 9, 18, 9, 22 ],
+ "className" : "bar"
+ }
+ }, {
+ "kind" : "TypedVar",
+ "location" : [ 9, 25, 9, 33 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 25, 9, 26 ],
+ "name" : "xx"
+ },
+ "type" : {
+ "kind" : "ListType",
+ "location" : [ 9, 29, 9, 33 ],
+ "elementType" : {
+ "kind" : "ClassType",
+ "location" : [ 9, 30, 9, 32 ],
+ "className" : "int"
+ }
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 9, 39, 9, 41 ],
+ "className" : "str"
+ },
+ "declarations" : [ {
+ "kind" : "GlobalDecl",
+ "location" : [ 10, 9, 10, 20 ],
+ "variable" : {
+ "kind" : "Identifier",
+ "location" : [ 10, 16, 10, 20 ],
+ "name" : "count"
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 11, 9, 11, 17 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 11, 9, 11, 13 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 9, 11, 9 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 11, 11, 11, 13 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 11, 17, 11, 17 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 0
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 12, 9, 12, 17 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 12, 9, 12, 13 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 12, 9, 12, 9 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 12, 11, 12, 13 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 12, 17, 12, 17 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 14, 9, 19, 8 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 14, 13, 14, 15 ],
+ "name" : "qux"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 14, 17, 14, 22 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 14, 17, 14, 17 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 14, 20, 14, 22 ],
+ "className" : "int"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 14, 28, 14, 33 ],
+ "className" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "NonLocalDecl",
+ "location" : [ 15, 13, 15, 22 ],
+ "variable" : {
+ "kind" : "Identifier",
+ "location" : [ 15, 22, 15, 22 ],
+ "name" : "x"
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "IfStmt",
+ "location" : [ 16, 13, 19, 8 ],
+ "condition" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 16, 16, 16, 20 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "left" : {
+ "kind" : "Identifier",
+ "location" : [ 16, 16, 16, 16 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "x"
+ },
+ "operator" : ">",
+ "right" : {
+ "kind" : "Identifier",
+ "location" : [ 16, 20, 16, 20 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "y"
+ }
+ },
+ "thenBody" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 17, 17, 17, 22 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 17, 17, 17, 17 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "x"
+ } ],
+ "value" : {
+ "kind" : "UnaryExpr",
+ "location" : [ 17, 21, 17, 22 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "operator" : "-",
+ "operand" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 17, 22, 17, 22 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ }
+ } ],
+ "elseBody" : [ ]
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ForStmt",
+ "location" : [ 19, 9, 22, 8 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 19, 13, 19, 13 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "x"
+ },
+ "iterable" : {
+ "kind" : "Identifier",
+ "location" : [ 19, 18, 19, 19 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "name" : "xx"
+ },
+ "body" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 20, 13, 20, 27 ],
+ "targets" : [ {
+ "kind" : "MemberExpr",
+ "location" : [ 20, 13, 20, 18 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 20, 13, 20, 16 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bar"
+ },
+ "name" : "self"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 20, 18, 20, 18 ],
+ "name" : "p"
+ }
+ } ],
+ "value" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 20, 22, 20, 27 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "left" : {
+ "kind" : "Identifier",
+ "location" : [ 20, 22, 20, 22 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "x"
+ },
+ "operator" : "==",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 20, 27, 20, 27 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 2
+ }
+ }
+ } ]
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 22, 9, 22, 14 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 22, 9, 22, 14 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 22, 9, 22, 11 ],
+ "inferredType" : {
+ "kind" : "FuncType",
+ "parameters" : [ {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ } ],
+ "returnType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ }
+ },
+ "name" : "qux"
+ },
+ "args" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 22, 13, 22, 13 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 0
+ } ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 24, 9, 24, 25 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 24, 9, 24, 13 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "count"
+ } ],
+ "value" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 24, 17, 24, 25 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "left" : {
+ "kind" : "Identifier",
+ "location" : [ 24, 17, 24, 21 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "count"
+ },
+ "operator" : "+",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 24, 25, 24, 25 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ }
+ }, {
+ "kind" : "WhileStmt",
+ "location" : [ 26, 9, 34, 8 ],
+ "condition" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 26, 15, 26, 20 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "left" : {
+ "kind" : "Identifier",
+ "location" : [ 26, 15, 26, 15 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "x"
+ },
+ "operator" : "<=",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 26, 20, 26, 20 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 0
+ }
+ },
+ "body" : [ {
+ "kind" : "IfStmt",
+ "location" : [ 27, 13, 34, 8 ],
+ "condition" : {
+ "kind" : "MemberExpr",
+ "location" : [ 27, 16, 27, 21 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 27, 16, 27, 19 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bar"
+ },
+ "name" : "self"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 27, 21, 27, 21 ],
+ "name" : "p"
+ }
+ },
+ "thenBody" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 28, 17, 28, 29 ],
+ "targets" : [ {
+ "kind" : "IndexExpr",
+ "location" : [ 28, 17, 28, 21 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "list" : {
+ "kind" : "Identifier",
+ "location" : [ 28, 17, 28, 18 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "name" : "xx"
+ },
+ "index" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 28, 20, 28, 20 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 0
+ }
+ } ],
+ "value" : {
+ "kind" : "IndexExpr",
+ "location" : [ 28, 25, 28, 29 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "list" : {
+ "kind" : "Identifier",
+ "location" : [ 28, 25, 28, 26 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "name" : "xx"
+ },
+ "index" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 28, 28, 28, 28 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 29, 17, 29, 35 ],
+ "targets" : [ {
+ "kind" : "MemberExpr",
+ "location" : [ 29, 17, 29, 22 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 29, 17, 29, 20 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bar"
+ },
+ "name" : "self"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 29, 22, 29, 22 ],
+ "name" : "p"
+ }
+ } ],
+ "value" : {
+ "kind" : "UnaryExpr",
+ "location" : [ 29, 26, 29, 35 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "operator" : "not",
+ "operand" : {
+ "kind" : "MemberExpr",
+ "location" : [ 29, 30, 29, 35 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 29, 30, 29, 33 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bar"
+ },
+ "name" : "self"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 29, 35, 29, 35 ],
+ "name" : "p"
+ }
+ }
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 30, 17, 30, 25 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 30, 17, 30, 17 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "x"
+ } ],
+ "value" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 30, 21, 30, 25 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "left" : {
+ "kind" : "Identifier",
+ "location" : [ 30, 21, 30, 21 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "x"
+ },
+ "operator" : "+",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 30, 25, 30, 25 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ }
+ } ],
+ "elseBody" : [ {
+ "kind" : "IfStmt",
+ "location" : [ 31, 13, 34, 8 ],
+ "condition" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 31, 18, 31, 36 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "left" : {
+ "kind" : "CallExpr",
+ "location" : [ 31, 18, 31, 31 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 31, 18, 31, 20 ],
+ "inferredType" : {
+ "kind" : "FuncType",
+ "parameters" : [ {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ } ],
+ "returnType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "name" : "foo"
+ },
+ "args" : [ {
+ "kind" : "IndexExpr",
+ "location" : [ 31, 22, 31, 30 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "list" : {
+ "kind" : "StringLiteral",
+ "location" : [ 31, 22, 31, 27 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "value" : "Long"
+ },
+ "index" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 31, 29, 31, 29 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 0
+ }
+ } ]
+ },
+ "operator" : "==",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 31, 36, 31, 36 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ },
+ "thenBody" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 32, 17, 32, 37 ],
+ "targets" : [ {
+ "kind" : "MemberExpr",
+ "location" : [ 32, 17, 32, 22 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 32, 17, 32, 20 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bar"
+ },
+ "name" : "self"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 32, 22, 32, 22 ],
+ "name" : "p"
+ }
+ } ],
+ "value" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 32, 26, 32, 37 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "left" : {
+ "kind" : "Identifier",
+ "location" : [ 32, 26, 32, 29 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bar"
+ },
+ "name" : "self"
+ },
+ "operator" : "is",
+ "right" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 32, 34, 32, 37 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ }
+ } ],
+ "elseBody" : [ ]
+ } ]
+ } ]
+ }, {
+ "kind" : "ReturnStmt",
+ "location" : [ 34, 9, 34, 21 ],
+ "value" : {
+ "kind" : "StringLiteral",
+ "location" : [ 34, 16, 34, 21 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "value" : "Nope"
+ }
+ } ]
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 36, 1, 36, 23 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 36, 1, 36, 23 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 36, 1, 36, 5 ],
+ "inferredType" : {
+ "kind" : "FuncType",
+ "parameters" : [ {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ } ],
+ "returnType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ },
+ "name" : "print"
+ },
+ "args" : [ {
+ "kind" : "MethodCallExpr",
+ "location" : [ 36, 7, 36, 22 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "method" : {
+ "kind" : "MemberExpr",
+ "location" : [ 36, 7, 36, 15 ],
+ "inferredType" : {
+ "kind" : "FuncType",
+ "parameters" : [ {
+ "kind" : "ClassValueType",
+ "className" : "bar"
+ }, {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ }
+ },
+ "object" : {
+ "kind" : "CallExpr",
+ "location" : [ 36, 7, 36, 11 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bar"
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 36, 7, 36, 9 ],
+ "name" : "bar"
+ },
+ "args" : [ ]
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 36, 13, 36, 15 ],
+ "name" : "baz"
+ }
+ },
+ "args" : [ {
+ "kind" : "ListExpr",
+ "location" : [ 36, 17, 36, 21 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "elements" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 36, 18, 36, 18 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }, {
+ "kind" : "IntegerLiteral",
+ "location" : [ 36, 20, 36, 20 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 2
+ } ]
+ } ]
+ } ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_assign_expr.py b/src/test/data/pa2/sample/bad_assign_expr.py
new file mode 100644
index 0000000..9e68917
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_assign_expr.py
@@ -0,0 +1,11 @@
+x:int = 0
+y:int = 0
+z:bool = False
+
+x = z = 1 # Only one error here (assignment to `x = 1` should succeed)
+x = y = None
+x = y = []
+x = a = None
+x = a = []
+x = y = True
+
diff --git a/src/test/data/pa2/sample/bad_assign_expr.py.ast b/src/test/data/pa2/sample/bad_assign_expr.py.ast
new file mode 100644
index 0000000..6651bd2
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_assign_expr.py.ast
@@ -0,0 +1,177 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 10, 13 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 3, 1, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 9, 1, 9 ],
+ "value" : 0
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 2, 1, 2, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 1, 2, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 1, 2, 1 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 3, 2, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 9, 2, 9 ],
+ "value" : 0
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 3, 1, 3, 14 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 3, 1, 3, 6 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 1, 3, 1 ],
+ "name" : "z"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 3, 3, 3, 6 ],
+ "className" : "bool"
+ }
+ },
+ "value" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 3, 10, 3, 14 ],
+ "value" : false
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 5, 1, 5, 9 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 5, 1, 5, 1 ],
+ "name" : "x"
+ }, {
+ "kind" : "Identifier",
+ "location" : [ 5, 5, 5, 5 ],
+ "name" : "z"
+ } ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 5, 9, 5, 9 ],
+ "value" : 1
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 6, 1, 6, 12 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 6, 1, 6, 1 ],
+ "name" : "x"
+ }, {
+ "kind" : "Identifier",
+ "location" : [ 6, 5, 6, 5 ],
+ "name" : "y"
+ } ],
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 6, 9, 6, 12 ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 7, 1, 7, 10 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 7, 1, 7, 1 ],
+ "name" : "x"
+ }, {
+ "kind" : "Identifier",
+ "location" : [ 7, 5, 7, 5 ],
+ "name" : "y"
+ } ],
+ "value" : {
+ "kind" : "ListExpr",
+ "location" : [ 7, 9, 7, 10 ],
+ "elements" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 8, 1, 8, 12 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 8, 1, 8, 1 ],
+ "name" : "x"
+ }, {
+ "kind" : "Identifier",
+ "location" : [ 8, 5, 8, 5 ],
+ "name" : "a"
+ } ],
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 8, 9, 8, 12 ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 9, 1, 9, 10 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 9, 1, 9, 1 ],
+ "name" : "x"
+ }, {
+ "kind" : "Identifier",
+ "location" : [ 9, 5, 9, 5 ],
+ "name" : "a"
+ } ],
+ "value" : {
+ "kind" : "ListExpr",
+ "location" : [ 9, 9, 9, 10 ],
+ "elements" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 10, 1, 10, 12 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 10, 1, 10, 1 ],
+ "name" : "x"
+ }, {
+ "kind" : "Identifier",
+ "location" : [ 10, 5, 10, 5 ],
+ "name" : "y"
+ } ],
+ "value" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 10, 9, 10, 12 ],
+ "value" : true
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_assign_expr.py.ast.typed b/src/test/data/pa2/sample/bad_assign_expr.py.ast.typed
new file mode 100644
index 0000000..2f99fae
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_assign_expr.py.ast.typed
@@ -0,0 +1,301 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 10, 13 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 3, 1, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 9, 1, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 0
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 2, 1, 2, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 1, 2, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 1, 2, 1 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 3, 2, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 9, 2, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 0
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 3, 1, 3, 14 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 3, 1, 3, 6 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 1, 3, 1 ],
+ "name" : "z"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 3, 3, 3, 6 ],
+ "className" : "bool"
+ }
+ },
+ "value" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 3, 10, 3, 14 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : false
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 5, 1, 5, 9 ],
+ "errorMsg" : "Expected type `bool`; got type `int`",
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 5, 1, 5, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "x"
+ }, {
+ "kind" : "Identifier",
+ "location" : [ 5, 5, 5, 5 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "name" : "z"
+ } ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 5, 9, 5, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 6, 1, 6, 12 ],
+ "errorMsg" : "Expected type `int`; got type ``",
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 6, 1, 6, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "x"
+ }, {
+ "kind" : "Identifier",
+ "location" : [ 6, 5, 6, 5 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "y"
+ } ],
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 6, 9, 6, 12 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 7, 1, 7, 10 ],
+ "errorMsg" : "Expected type `int`; got type ``",
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 7, 1, 7, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "x"
+ }, {
+ "kind" : "Identifier",
+ "location" : [ 7, 5, 7, 5 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "y"
+ } ],
+ "value" : {
+ "kind" : "ListExpr",
+ "location" : [ 7, 9, 7, 10 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ },
+ "elements" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 8, 1, 8, 12 ],
+ "errorMsg" : "Expected type `int`; got type ``",
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 8, 1, 8, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "x"
+ }, {
+ "kind" : "Identifier",
+ "location" : [ 8, 5, 8, 5 ],
+ "errorMsg" : "Not a variable: a",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ },
+ "name" : "a"
+ } ],
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 8, 9, 8, 12 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 9, 1, 9, 10 ],
+ "errorMsg" : "Expected type `int`; got type ``",
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 9, 1, 9, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "x"
+ }, {
+ "kind" : "Identifier",
+ "location" : [ 9, 5, 9, 5 ],
+ "errorMsg" : "Not a variable: a",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ },
+ "name" : "a"
+ } ],
+ "value" : {
+ "kind" : "ListExpr",
+ "location" : [ 9, 9, 9, 10 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ },
+ "elements" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 10, 1, 10, 12 ],
+ "errorMsg" : "Expected type `int`; got type `bool`",
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 10, 1, 10, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "x"
+ }, {
+ "kind" : "Identifier",
+ "location" : [ 10, 5, 10, 5 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "y"
+ } ],
+ "value" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 10, 9, 10, 12 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : true
+ }
+ } ],
+ "errors" : {
+ "errors" : [ {
+ "kind" : "CompilerError",
+ "location" : [ 5, 1, 5, 9 ],
+ "message" : "Expected type `bool`; got type `int`"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 6, 1, 6, 12 ],
+ "message" : "Expected type `int`; got type ``"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 7, 1, 7, 10 ],
+ "message" : "Expected type `int`; got type ``"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 8, 1, 8, 12 ],
+ "message" : "Expected type `int`; got type ``"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 8, 5, 8, 5 ],
+ "message" : "Not a variable: a"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 9, 1, 9, 10 ],
+ "message" : "Expected type `int`; got type ``"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 9, 5, 9, 5 ],
+ "message" : "Not a variable: a"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 10, 1, 10, 12 ],
+ "message" : "Expected type `int`; got type `bool`"
+ } ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_class_attr.py b/src/test/data/pa2/sample/bad_class_attr.py
new file mode 100644
index 0000000..b30eb7c
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_class_attr.py
@@ -0,0 +1,13 @@
+class A(object):
+ x:int = 1
+
+ def foo(self:"A") -> int:
+ return 0
+
+class B(A):
+ x:int = 2 # Bad
+ foo:str = "" # Bad
+
+A()
+
+
diff --git a/src/test/data/pa2/sample/bad_class_attr.py.ast b/src/test/data/pa2/sample/bad_class_attr.py.ast
new file mode 100644
index 0000000..ec25404
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_class_attr.py.ast
@@ -0,0 +1,155 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 11, 4 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 1, 1, 7, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 7, 1, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 2, 5, 2, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 5, 2, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 5, 2, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 7, 2, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 13, 2, 13 ],
+ "value" : 1
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 4, 5, 5, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 9, 4, 11 ],
+ "name" : "foo"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 4, 13, 4, 20 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 13, 4, 16 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 18, 4, 20 ],
+ "className" : "A"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 26, 4, 28 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 5, 9, 5, 16 ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 5, 16, 5, 16 ],
+ "value" : 0
+ }
+ } ]
+ } ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 7, 1, 9, 23 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 7, 7, 7 ],
+ "name" : "B"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 9, 7, 9 ],
+ "name" : "A"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 8, 5, 8, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 8, 5, 8, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 5, 8, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 8, 7, 8, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 8, 13, 8, 13 ],
+ "value" : 2
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 9, 5, 9, 16 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 9, 5, 9, 11 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 5, 9, 7 ],
+ "name" : "foo"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 9, 9, 9, 11 ],
+ "className" : "str"
+ }
+ },
+ "value" : {
+ "kind" : "StringLiteral",
+ "location" : [ 9, 15, 9, 16 ],
+ "value" : ""
+ }
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 11, 1, 11, 3 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 11, 1, 11, 3 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 1, 11, 1 ],
+ "name" : "A"
+ },
+ "args" : [ ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_class_attr.py.ast.typed b/src/test/data/pa2/sample/bad_class_attr.py.ast.typed
new file mode 100644
index 0000000..5ea1e74
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_class_attr.py.ast.typed
@@ -0,0 +1,165 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 11, 4 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 1, 1, 7, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 7, 1, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 2, 5, 2, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 5, 2, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 5, 2, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 7, 2, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 13, 2, 13 ],
+ "value" : 1
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 4, 5, 5, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 9, 4, 11 ],
+ "name" : "foo"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 4, 13, 4, 20 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 13, 4, 16 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 18, 4, 20 ],
+ "className" : "A"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 26, 4, 28 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 5, 9, 5, 16 ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 5, 16, 5, 16 ],
+ "value" : 0
+ }
+ } ]
+ } ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 7, 1, 9, 23 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 7, 7, 7 ],
+ "name" : "B"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 9, 7, 9 ],
+ "name" : "A"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 8, 5, 8, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 8, 5, 8, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 5, 8, 5 ],
+ "errorMsg" : "Cannot re-define attribute: x",
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 8, 7, 8, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 8, 13, 8, 13 ],
+ "value" : 2
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 9, 5, 9, 16 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 9, 5, 9, 11 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 5, 9, 7 ],
+ "errorMsg" : "Cannot re-define attribute: foo",
+ "name" : "foo"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 9, 9, 9, 11 ],
+ "className" : "str"
+ }
+ },
+ "value" : {
+ "kind" : "StringLiteral",
+ "location" : [ 9, 15, 9, 16 ],
+ "value" : ""
+ }
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 11, 1, 11, 3 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 11, 1, 11, 3 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 1, 11, 1 ],
+ "name" : "A"
+ },
+ "args" : [ ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ {
+ "kind" : "CompilerError",
+ "location" : [ 8, 5, 8, 5 ],
+ "message" : "Cannot re-define attribute: x"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 9, 5, 9, 7 ],
+ "message" : "Cannot re-define attribute: foo"
+ } ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_class_attr_type.py b/src/test/data/pa2/sample/bad_class_attr_type.py
new file mode 100644
index 0000000..5a7bee7
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_class_attr_type.py
@@ -0,0 +1,4 @@
+class A(object):
+ x:int = True
+
+A()
diff --git a/src/test/data/pa2/sample/bad_class_attr_type.py.ast b/src/test/data/pa2/sample/bad_class_attr_type.py.ast
new file mode 100644
index 0000000..6b9d252
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_class_attr_type.py.ast
@@ -0,0 +1,60 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 4, 4 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 1, 1, 2, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 7, 1, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 2, 5, 2, 16 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 5, 2, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 5, 2, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 7, 2, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 2, 13, 2, 16 ],
+ "value" : true
+ }
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 4, 1, 4, 3 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 4, 1, 4, 3 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 1, 4, 1 ],
+ "name" : "A"
+ },
+ "args" : [ ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_class_attr_type.py.ast.typed b/src/test/data/pa2/sample/bad_class_attr_type.py.ast.typed
new file mode 100644
index 0000000..f0a9461
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_class_attr_type.py.ast.typed
@@ -0,0 +1,73 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 4, 4 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 1, 1, 2, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 7, 1, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 2, 5, 2, 16 ],
+ "errorMsg" : "Expected type `int`; got type `bool`",
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 5, 2, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 5, 2, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 7, 2, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 2, 13, 2, 16 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : true
+ }
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 4, 1, 4, 3 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 4, 1, 4, 3 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "A"
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 1, 4, 1 ],
+ "name" : "A"
+ },
+ "args" : [ ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ {
+ "kind" : "CompilerError",
+ "location" : [ 2, 5, 2, 16 ],
+ "message" : "Expected type `int`; got type `bool`"
+ } ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_class_init_override.py b/src/test/data/pa2/sample/bad_class_init_override.py
new file mode 100644
index 0000000..ceb612c
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_class_init_override.py
@@ -0,0 +1,8 @@
+class A(object):
+ x:int = 1
+
+ def __init__(self:"A", x:int): # Bad override
+ pass
+
+A(1)
+
diff --git a/src/test/data/pa2/sample/bad_class_init_override.py.ast b/src/test/data/pa2/sample/bad_class_init_override.py.ast
new file mode 100644
index 0000000..bdd151d
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_class_init_override.py.ast
@@ -0,0 +1,106 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 7, 5 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 1, 1, 7, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 7, 1, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 2, 5, 2, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 5, 2, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 5, 2, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 7, 2, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 13, 2, 13 ],
+ "value" : 1
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 4, 5, 5, 13 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 9, 4, 16 ],
+ "name" : "__init__"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 4, 18, 4, 25 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 18, 4, 21 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 23, 4, 25 ],
+ "className" : "A"
+ }
+ }, {
+ "kind" : "TypedVar",
+ "location" : [ 4, 28, 4, 32 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 28, 4, 28 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 30, 4, 32 ],
+ "className" : "int"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 34, 4, 34 ],
+ "className" : ""
+ },
+ "declarations" : [ ],
+ "statements" : [ ]
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 7, 1, 7, 4 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 7, 1, 7, 4 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 1, 7, 1 ],
+ "name" : "A"
+ },
+ "args" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 7, 3, 7, 3 ],
+ "value" : 1
+ } ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_class_init_override.py.ast.typed b/src/test/data/pa2/sample/bad_class_init_override.py.ast.typed
new file mode 100644
index 0000000..9daa89c
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_class_init_override.py.ast.typed
@@ -0,0 +1,111 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 7, 5 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 1, 1, 7, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 7, 1, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 2, 5, 2, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 5, 2, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 5, 2, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 7, 2, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 13, 2, 13 ],
+ "value" : 1
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 4, 5, 5, 13 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 9, 4, 16 ],
+ "errorMsg" : "Method overridden with different type signature: __init__",
+ "name" : "__init__"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 4, 18, 4, 25 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 18, 4, 21 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 23, 4, 25 ],
+ "className" : "A"
+ }
+ }, {
+ "kind" : "TypedVar",
+ "location" : [ 4, 28, 4, 32 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 28, 4, 28 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 30, 4, 32 ],
+ "className" : "int"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 34, 4, 34 ],
+ "className" : ""
+ },
+ "declarations" : [ ],
+ "statements" : [ ]
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 7, 1, 7, 4 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 7, 1, 7, 4 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 1, 7, 1 ],
+ "name" : "A"
+ },
+ "args" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 7, 3, 7, 3 ],
+ "value" : 1
+ } ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ {
+ "kind" : "CompilerError",
+ "location" : [ 4, 9, 4, 16 ],
+ "message" : "Method overridden with different type signature: __init__"
+ } ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_class_init_return.py b/src/test/data/pa2/sample/bad_class_init_return.py
new file mode 100644
index 0000000..cc6eb34
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_class_init_return.py
@@ -0,0 +1,5 @@
+class A(object):
+ def __init__(self:"A"):
+ return 1 # Bad
+
+A()
diff --git a/src/test/data/pa2/sample/bad_class_init_return.py.ast b/src/test/data/pa2/sample/bad_class_init_return.py.ast
new file mode 100644
index 0000000..24e972f
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_class_init_return.py.ast
@@ -0,0 +1,75 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 5, 4 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 1, 1, 5, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 7, 1, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "FuncDef",
+ "location" : [ 2, 5, 3, 23 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 9, 2, 16 ],
+ "name" : "__init__"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 2, 18, 2, 25 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 18, 2, 21 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 23, 2, 25 ],
+ "className" : "A"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 27, 2, 27 ],
+ "className" : ""
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 3, 9, 3, 16 ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 3, 16, 3, 16 ],
+ "value" : 1
+ }
+ } ]
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 5, 1, 5, 3 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 5, 1, 5, 3 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 1, 5, 1 ],
+ "name" : "A"
+ },
+ "args" : [ ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_class_init_return.py.ast.typed b/src/test/data/pa2/sample/bad_class_init_return.py.ast.typed
new file mode 100644
index 0000000..cf0cde2
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_class_init_return.py.ast.typed
@@ -0,0 +1,88 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 5, 4 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 1, 1, 5, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 7, 1, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "FuncDef",
+ "location" : [ 2, 5, 3, 23 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 9, 2, 16 ],
+ "name" : "__init__"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 2, 18, 2, 25 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 18, 2, 21 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 23, 2, 25 ],
+ "className" : "A"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 27, 2, 27 ],
+ "className" : ""
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 3, 9, 3, 16 ],
+ "errorMsg" : "Expected type ``; got type `int`",
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 3, 16, 3, 16 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ } ]
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 5, 1, 5, 3 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 5, 1, 5, 3 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "A"
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 1, 5, 1 ],
+ "name" : "A"
+ },
+ "args" : [ ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ {
+ "kind" : "CompilerError",
+ "location" : [ 3, 9, 3, 16 ],
+ "message" : "Expected type ``; got type `int`"
+ } ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_class_member_expr.py b/src/test/data/pa2/sample/bad_class_member_expr.py
new file mode 100644
index 0000000..bbfa1c1
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_class_member_expr.py
@@ -0,0 +1,6 @@
+x:int = 0
+o:object = None
+
+x.foo
+o.bar
+o.baz = 1
diff --git a/src/test/data/pa2/sample/bad_class_member_expr.py.ast b/src/test/data/pa2/sample/bad_class_member_expr.py.ast
new file mode 100644
index 0000000..4949375
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_class_member_expr.py.ast
@@ -0,0 +1,110 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 6, 10 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 3, 1, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 9, 1, 9 ],
+ "value" : 0
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 2, 1, 2, 15 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 1, 2, 8 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 1, 2, 1 ],
+ "name" : "o"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 3, 2, 8 ],
+ "className" : "object"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 2, 12, 2, 15 ]
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 4, 1, 4, 5 ],
+ "expr" : {
+ "kind" : "MemberExpr",
+ "location" : [ 4, 1, 4, 5 ],
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 1, 4, 1 ],
+ "name" : "x"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 3, 4, 5 ],
+ "name" : "foo"
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 5, 1, 5, 5 ],
+ "expr" : {
+ "kind" : "MemberExpr",
+ "location" : [ 5, 1, 5, 5 ],
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 1, 5, 1 ],
+ "name" : "o"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 3, 5, 5 ],
+ "name" : "bar"
+ }
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 6, 1, 6, 9 ],
+ "targets" : [ {
+ "kind" : "MemberExpr",
+ "location" : [ 6, 1, 6, 5 ],
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 6, 1, 6, 1 ],
+ "name" : "o"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 6, 3, 6, 5 ],
+ "name" : "baz"
+ }
+ } ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 9, 6, 9 ],
+ "value" : 1
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_class_member_expr.py.ast.typed b/src/test/data/pa2/sample/bad_class_member_expr.py.ast.typed
new file mode 100644
index 0000000..4e570c0
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_class_member_expr.py.ast.typed
@@ -0,0 +1,161 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 6, 10 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 3, 1, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 9, 1, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 0
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 2, 1, 2, 15 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 1, 2, 8 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 1, 2, 1 ],
+ "name" : "o"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 3, 2, 8 ],
+ "className" : "object"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 2, 12, 2, 15 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 4, 1, 4, 5 ],
+ "expr" : {
+ "kind" : "MemberExpr",
+ "location" : [ 4, 1, 4, 5 ],
+ "errorMsg" : "There is no attribute named `foo` in class `int`",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ },
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 1, 4, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "x"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 3, 4, 5 ],
+ "name" : "foo"
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 5, 1, 5, 5 ],
+ "expr" : {
+ "kind" : "MemberExpr",
+ "location" : [ 5, 1, 5, 5 ],
+ "errorMsg" : "There is no attribute named `bar` in class `object`",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ },
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 1, 5, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ },
+ "name" : "o"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 3, 5, 5 ],
+ "name" : "bar"
+ }
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 6, 1, 6, 9 ],
+ "targets" : [ {
+ "kind" : "MemberExpr",
+ "location" : [ 6, 1, 6, 5 ],
+ "errorMsg" : "There is no attribute named `baz` in class `object`",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ },
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 6, 1, 6, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ },
+ "name" : "o"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 6, 3, 6, 5 ],
+ "name" : "baz"
+ }
+ } ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 9, 6, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ } ],
+ "errors" : {
+ "errors" : [ {
+ "kind" : "CompilerError",
+ "location" : [ 4, 1, 4, 5 ],
+ "message" : "There is no attribute named `foo` in class `int`"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 5, 1, 5, 5 ],
+ "message" : "There is no attribute named `bar` in class `object`"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 6, 1, 6, 5 ],
+ "message" : "There is no attribute named `baz` in class `object`"
+ } ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_class_method.py b/src/test/data/pa2/sample/bad_class_method.py
new file mode 100644
index 0000000..d5a10d8
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_class_method.py
@@ -0,0 +1,14 @@
+class A(object):
+ x:int = 1
+
+ def foo(self:"A") -> int: # OK
+ return 0
+
+ def bar() -> int: # Needs self param
+ return 0
+
+ def baz(self:int) -> int: # Incorrect self type
+ return 0
+
+A()
+
diff --git a/src/test/data/pa2/sample/bad_class_method.py.ast b/src/test/data/pa2/sample/bad_class_method.py.ast
new file mode 100644
index 0000000..7c359ef
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_class_method.py.ast
@@ -0,0 +1,158 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 13, 4 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 1, 1, 13, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 7, 1, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 2, 5, 2, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 5, 2, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 5, 2, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 7, 2, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 13, 2, 13 ],
+ "value" : 1
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 4, 5, 5, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 9, 4, 11 ],
+ "name" : "foo"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 4, 13, 4, 20 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 13, 4, 16 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 18, 4, 20 ],
+ "className" : "A"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 26, 4, 28 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 5, 9, 5, 16 ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 5, 16, 5, 16 ],
+ "value" : 0
+ }
+ } ]
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 7, 5, 8, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 9, 7, 11 ],
+ "name" : "bar"
+ },
+ "params" : [ ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 7, 18, 7, 20 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 8, 9, 8, 16 ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 8, 16, 8, 16 ],
+ "value" : 0
+ }
+ } ]
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 10, 5, 11, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 10, 9, 10, 11 ],
+ "name" : "baz"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 10, 13, 10, 20 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 10, 13, 10, 16 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 10, 18, 10, 20 ],
+ "className" : "int"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 10, 26, 10, 28 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 11, 9, 11, 16 ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 11, 16, 11, 16 ],
+ "value" : 0
+ }
+ } ]
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 13, 1, 13, 3 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 13, 1, 13, 3 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 13, 1, 13, 1 ],
+ "name" : "A"
+ },
+ "args" : [ ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_class_method.py.ast.typed b/src/test/data/pa2/sample/bad_class_method.py.ast.typed
new file mode 100644
index 0000000..9e08da8
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_class_method.py.ast.typed
@@ -0,0 +1,168 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 13, 4 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 1, 1, 13, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 7, 1, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 2, 5, 2, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 5, 2, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 5, 2, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 7, 2, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 13, 2, 13 ],
+ "value" : 1
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 4, 5, 5, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 9, 4, 11 ],
+ "name" : "foo"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 4, 13, 4, 20 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 13, 4, 16 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 18, 4, 20 ],
+ "className" : "A"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 26, 4, 28 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 5, 9, 5, 16 ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 5, 16, 5, 16 ],
+ "value" : 0
+ }
+ } ]
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 7, 5, 8, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 9, 7, 11 ],
+ "errorMsg" : "First parameter of the following method must be of the enclosing class: bar",
+ "name" : "bar"
+ },
+ "params" : [ ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 7, 18, 7, 20 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 8, 9, 8, 16 ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 8, 16, 8, 16 ],
+ "value" : 0
+ }
+ } ]
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 10, 5, 11, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 10, 9, 10, 11 ],
+ "errorMsg" : "First parameter of the following method must be of the enclosing class: baz",
+ "name" : "baz"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 10, 13, 10, 20 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 10, 13, 10, 16 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 10, 18, 10, 20 ],
+ "className" : "int"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 10, 26, 10, 28 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 11, 9, 11, 16 ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 11, 16, 11, 16 ],
+ "value" : 0
+ }
+ } ]
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 13, 1, 13, 3 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 13, 1, 13, 3 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 13, 1, 13, 1 ],
+ "name" : "A"
+ },
+ "args" : [ ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ {
+ "kind" : "CompilerError",
+ "location" : [ 7, 9, 7, 11 ],
+ "message" : "First parameter of the following method must be of the enclosing class: bar"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 10, 9, 10, 11 ],
+ "message" : "First parameter of the following method must be of the enclosing class: baz"
+ } ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_class_method_invoke.py b/src/test/data/pa2/sample/bad_class_method_invoke.py
new file mode 100644
index 0000000..d5bb97c
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_class_method_invoke.py
@@ -0,0 +1,30 @@
+class A(object):
+ x:int = 1
+
+ def get_A(self: "A") -> int:
+ return self.x
+
+class B(A):
+ def __init__(self: "B"):
+ pass
+
+class C(B):
+ z:bool = True
+
+ def set_A(self: "C", val: int) -> object:
+ self.x = val
+
+a:A = None
+b:B = None
+c:C = None
+
+a = A()
+b = B()
+c = C()
+
+a.get_A(1)
+b.get_Z()
+c.set_A()
+c.set_A(False)
+c.set_A(None)
+
diff --git a/src/test/data/pa2/sample/bad_class_method_invoke.py.ast b/src/test/data/pa2/sample/bad_class_method_invoke.py.ast
new file mode 100644
index 0000000..e01db23
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_class_method_invoke.py.ast
@@ -0,0 +1,474 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 29, 14 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 1, 1, 7, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 7, 1, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 2, 5, 2, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 5, 2, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 5, 2, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 7, 2, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 13, 2, 13 ],
+ "value" : 1
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 4, 5, 5, 22 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 9, 4, 13 ],
+ "name" : "get_A"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 4, 15, 4, 23 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 15, 4, 18 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 21, 4, 23 ],
+ "className" : "A"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 29, 4, 31 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 5, 9, 5, 21 ],
+ "value" : {
+ "kind" : "MemberExpr",
+ "location" : [ 5, 16, 5, 21 ],
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 16, 5, 19 ],
+ "name" : "self"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 21, 5, 21 ],
+ "name" : "x"
+ }
+ }
+ } ]
+ } ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 7, 1, 11, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 7, 7, 7 ],
+ "name" : "B"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 9, 7, 9 ],
+ "name" : "A"
+ },
+ "declarations" : [ {
+ "kind" : "FuncDef",
+ "location" : [ 8, 5, 9, 13 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 9, 8, 16 ],
+ "name" : "__init__"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 8, 18, 8, 26 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 18, 8, 21 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 8, 24, 8, 26 ],
+ "className" : "B"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 8, 28, 8, 28 ],
+ "className" : ""
+ },
+ "declarations" : [ ],
+ "statements" : [ ]
+ } ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 11, 1, 17, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 7, 11, 7 ],
+ "name" : "C"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 9, 11, 9 ],
+ "name" : "B"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 12, 5, 12, 17 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 12, 5, 12, 10 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 12, 5, 12, 5 ],
+ "name" : "z"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 12, 7, 12, 10 ],
+ "className" : "bool"
+ }
+ },
+ "value" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 12, 14, 12, 17 ],
+ "value" : true
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 14, 5, 15, 21 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 14, 9, 14, 13 ],
+ "name" : "set_A"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 14, 15, 14, 23 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 14, 15, 14, 18 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 14, 21, 14, 23 ],
+ "className" : "C"
+ }
+ }, {
+ "kind" : "TypedVar",
+ "location" : [ 14, 26, 14, 33 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 14, 26, 14, 28 ],
+ "name" : "val"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 14, 31, 14, 33 ],
+ "className" : "int"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 14, 39, 14, 44 ],
+ "className" : "object"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 15, 9, 15, 20 ],
+ "targets" : [ {
+ "kind" : "MemberExpr",
+ "location" : [ 15, 9, 15, 14 ],
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 15, 9, 15, 12 ],
+ "name" : "self"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 15, 14, 15, 14 ],
+ "name" : "x"
+ }
+ } ],
+ "value" : {
+ "kind" : "Identifier",
+ "location" : [ 15, 18, 15, 20 ],
+ "name" : "val"
+ }
+ } ]
+ } ]
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 17, 1, 17, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 17, 1, 17, 3 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 17, 1, 17, 1 ],
+ "name" : "a"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 17, 3, 17, 3 ],
+ "className" : "A"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 17, 7, 17, 10 ]
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 18, 1, 18, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 18, 1, 18, 3 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 18, 1, 18, 1 ],
+ "name" : "b"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 18, 3, 18, 3 ],
+ "className" : "B"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 18, 7, 18, 10 ]
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 19, 1, 19, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 19, 1, 19, 3 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 19, 1, 19, 1 ],
+ "name" : "c"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 19, 3, 19, 3 ],
+ "className" : "C"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 19, 7, 19, 10 ]
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 21, 1, 21, 7 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 21, 1, 21, 1 ],
+ "name" : "a"
+ } ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 21, 5, 21, 7 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 21, 5, 21, 5 ],
+ "name" : "A"
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 22, 1, 22, 7 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 22, 1, 22, 1 ],
+ "name" : "b"
+ } ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 22, 5, 22, 7 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 22, 5, 22, 5 ],
+ "name" : "B"
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 23, 1, 23, 7 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 23, 1, 23, 1 ],
+ "name" : "c"
+ } ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 23, 5, 23, 7 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 23, 5, 23, 5 ],
+ "name" : "C"
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 25, 1, 25, 10 ],
+ "expr" : {
+ "kind" : "MethodCallExpr",
+ "location" : [ 25, 1, 25, 10 ],
+ "method" : {
+ "kind" : "MemberExpr",
+ "location" : [ 25, 1, 25, 7 ],
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 25, 1, 25, 1 ],
+ "name" : "a"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 25, 3, 25, 7 ],
+ "name" : "get_A"
+ }
+ },
+ "args" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 25, 9, 25, 9 ],
+ "value" : 1
+ } ]
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 26, 1, 26, 9 ],
+ "expr" : {
+ "kind" : "MethodCallExpr",
+ "location" : [ 26, 1, 26, 9 ],
+ "method" : {
+ "kind" : "MemberExpr",
+ "location" : [ 26, 1, 26, 7 ],
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 26, 1, 26, 1 ],
+ "name" : "b"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 26, 3, 26, 7 ],
+ "name" : "get_Z"
+ }
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 27, 1, 27, 9 ],
+ "expr" : {
+ "kind" : "MethodCallExpr",
+ "location" : [ 27, 1, 27, 9 ],
+ "method" : {
+ "kind" : "MemberExpr",
+ "location" : [ 27, 1, 27, 7 ],
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 27, 1, 27, 1 ],
+ "name" : "c"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 27, 3, 27, 7 ],
+ "name" : "set_A"
+ }
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 28, 1, 28, 14 ],
+ "expr" : {
+ "kind" : "MethodCallExpr",
+ "location" : [ 28, 1, 28, 14 ],
+ "method" : {
+ "kind" : "MemberExpr",
+ "location" : [ 28, 1, 28, 7 ],
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 28, 1, 28, 1 ],
+ "name" : "c"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 28, 3, 28, 7 ],
+ "name" : "set_A"
+ }
+ },
+ "args" : [ {
+ "kind" : "BooleanLiteral",
+ "location" : [ 28, 9, 28, 13 ],
+ "value" : false
+ } ]
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 29, 1, 29, 13 ],
+ "expr" : {
+ "kind" : "MethodCallExpr",
+ "location" : [ 29, 1, 29, 13 ],
+ "method" : {
+ "kind" : "MemberExpr",
+ "location" : [ 29, 1, 29, 7 ],
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 29, 1, 29, 1 ],
+ "name" : "c"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 29, 3, 29, 7 ],
+ "name" : "set_A"
+ }
+ },
+ "args" : [ {
+ "kind" : "NoneLiteral",
+ "location" : [ 29, 9, 29, 12 ]
+ } ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_class_method_invoke.py.ast.typed b/src/test/data/pa2/sample/bad_class_method_invoke.py.ast.typed
new file mode 100644
index 0000000..77867db
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_class_method_invoke.py.ast.typed
@@ -0,0 +1,668 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 29, 14 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 1, 1, 7, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 7, 1, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 2, 5, 2, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 5, 2, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 5, 2, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 7, 2, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 13, 2, 13 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 4, 5, 5, 22 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 9, 4, 13 ],
+ "name" : "get_A"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 4, 15, 4, 23 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 15, 4, 18 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 21, 4, 23 ],
+ "className" : "A"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 29, 4, 31 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 5, 9, 5, 21 ],
+ "value" : {
+ "kind" : "MemberExpr",
+ "location" : [ 5, 16, 5, 21 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 16, 5, 19 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "A"
+ },
+ "name" : "self"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 21, 5, 21 ],
+ "name" : "x"
+ }
+ }
+ } ]
+ } ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 7, 1, 11, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 7, 7, 7 ],
+ "name" : "B"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 9, 7, 9 ],
+ "name" : "A"
+ },
+ "declarations" : [ {
+ "kind" : "FuncDef",
+ "location" : [ 8, 5, 9, 13 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 9, 8, 16 ],
+ "name" : "__init__"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 8, 18, 8, 26 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 18, 8, 21 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 8, 24, 8, 26 ],
+ "className" : "B"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 8, 28, 8, 28 ],
+ "className" : ""
+ },
+ "declarations" : [ ],
+ "statements" : [ ]
+ } ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 11, 1, 17, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 7, 11, 7 ],
+ "name" : "C"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 9, 11, 9 ],
+ "name" : "B"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 12, 5, 12, 17 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 12, 5, 12, 10 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 12, 5, 12, 5 ],
+ "name" : "z"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 12, 7, 12, 10 ],
+ "className" : "bool"
+ }
+ },
+ "value" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 12, 14, 12, 17 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : true
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 14, 5, 15, 21 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 14, 9, 14, 13 ],
+ "name" : "set_A"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 14, 15, 14, 23 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 14, 15, 14, 18 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 14, 21, 14, 23 ],
+ "className" : "C"
+ }
+ }, {
+ "kind" : "TypedVar",
+ "location" : [ 14, 26, 14, 33 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 14, 26, 14, 28 ],
+ "name" : "val"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 14, 31, 14, 33 ],
+ "className" : "int"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 14, 39, 14, 44 ],
+ "className" : "object"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 15, 9, 15, 20 ],
+ "targets" : [ {
+ "kind" : "MemberExpr",
+ "location" : [ 15, 9, 15, 14 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 15, 9, 15, 12 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "C"
+ },
+ "name" : "self"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 15, 14, 15, 14 ],
+ "name" : "x"
+ }
+ } ],
+ "value" : {
+ "kind" : "Identifier",
+ "location" : [ 15, 18, 15, 20 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "val"
+ }
+ } ]
+ } ]
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 17, 1, 17, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 17, 1, 17, 3 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 17, 1, 17, 1 ],
+ "name" : "a"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 17, 3, 17, 3 ],
+ "className" : "A"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 17, 7, 17, 10 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 18, 1, 18, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 18, 1, 18, 3 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 18, 1, 18, 1 ],
+ "name" : "b"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 18, 3, 18, 3 ],
+ "className" : "B"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 18, 7, 18, 10 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 19, 1, 19, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 19, 1, 19, 3 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 19, 1, 19, 1 ],
+ "name" : "c"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 19, 3, 19, 3 ],
+ "className" : "C"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 19, 7, 19, 10 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 21, 1, 21, 7 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 21, 1, 21, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "A"
+ },
+ "name" : "a"
+ } ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 21, 5, 21, 7 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "A"
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 21, 5, 21, 5 ],
+ "name" : "A"
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 22, 1, 22, 7 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 22, 1, 22, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "B"
+ },
+ "name" : "b"
+ } ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 22, 5, 22, 7 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "B"
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 22, 5, 22, 5 ],
+ "name" : "B"
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 23, 1, 23, 7 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 23, 1, 23, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "C"
+ },
+ "name" : "c"
+ } ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 23, 5, 23, 7 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "C"
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 23, 5, 23, 5 ],
+ "name" : "C"
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 25, 1, 25, 10 ],
+ "expr" : {
+ "kind" : "MethodCallExpr",
+ "location" : [ 25, 1, 25, 10 ],
+ "errorMsg" : "Expected 0 arguments; got 1",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "method" : {
+ "kind" : "MemberExpr",
+ "location" : [ 25, 1, 25, 7 ],
+ "inferredType" : {
+ "kind" : "FuncType",
+ "parameters" : [ {
+ "kind" : "ClassValueType",
+ "className" : "A"
+ } ],
+ "returnType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 25, 1, 25, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "A"
+ },
+ "name" : "a"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 25, 3, 25, 7 ],
+ "name" : "get_A"
+ }
+ },
+ "args" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 25, 9, 25, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ } ]
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 26, 1, 26, 9 ],
+ "expr" : {
+ "kind" : "MethodCallExpr",
+ "location" : [ 26, 1, 26, 9 ],
+ "errorMsg" : "There is no method named `get_Z` in class `B`",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ },
+ "method" : {
+ "kind" : "MemberExpr",
+ "location" : [ 26, 1, 26, 7 ],
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 26, 1, 26, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "B"
+ },
+ "name" : "b"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 26, 3, 26, 7 ],
+ "name" : "get_Z"
+ }
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 27, 1, 27, 9 ],
+ "expr" : {
+ "kind" : "MethodCallExpr",
+ "location" : [ 27, 1, 27, 9 ],
+ "errorMsg" : "Expected 1 arguments; got 0",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ },
+ "method" : {
+ "kind" : "MemberExpr",
+ "location" : [ 27, 1, 27, 7 ],
+ "inferredType" : {
+ "kind" : "FuncType",
+ "parameters" : [ {
+ "kind" : "ClassValueType",
+ "className" : "C"
+ }, {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ } ],
+ "returnType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ }
+ },
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 27, 1, 27, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "C"
+ },
+ "name" : "c"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 27, 3, 27, 7 ],
+ "name" : "set_A"
+ }
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 28, 1, 28, 14 ],
+ "expr" : {
+ "kind" : "MethodCallExpr",
+ "location" : [ 28, 1, 28, 14 ],
+ "errorMsg" : "Expected type `int`; got type `bool` in parameter 1",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ },
+ "method" : {
+ "kind" : "MemberExpr",
+ "location" : [ 28, 1, 28, 7 ],
+ "inferredType" : {
+ "kind" : "FuncType",
+ "parameters" : [ {
+ "kind" : "ClassValueType",
+ "className" : "C"
+ }, {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ } ],
+ "returnType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ }
+ },
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 28, 1, 28, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "C"
+ },
+ "name" : "c"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 28, 3, 28, 7 ],
+ "name" : "set_A"
+ }
+ },
+ "args" : [ {
+ "kind" : "BooleanLiteral",
+ "location" : [ 28, 9, 28, 13 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : false
+ } ]
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 29, 1, 29, 13 ],
+ "expr" : {
+ "kind" : "MethodCallExpr",
+ "location" : [ 29, 1, 29, 13 ],
+ "errorMsg" : "Expected type `int`; got type `` in parameter 1",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ },
+ "method" : {
+ "kind" : "MemberExpr",
+ "location" : [ 29, 1, 29, 7 ],
+ "inferredType" : {
+ "kind" : "FuncType",
+ "parameters" : [ {
+ "kind" : "ClassValueType",
+ "className" : "C"
+ }, {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ } ],
+ "returnType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ }
+ },
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 29, 1, 29, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "C"
+ },
+ "name" : "c"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 29, 3, 29, 7 ],
+ "name" : "set_A"
+ }
+ },
+ "args" : [ {
+ "kind" : "NoneLiteral",
+ "location" : [ 29, 9, 29, 12 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ } ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ {
+ "kind" : "CompilerError",
+ "location" : [ 25, 1, 25, 10 ],
+ "message" : "Expected 0 arguments; got 1"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 26, 1, 26, 9 ],
+ "message" : "There is no method named `get_Z` in class `B`"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 27, 1, 27, 9 ],
+ "message" : "Expected 1 arguments; got 0"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 28, 1, 28, 14 ],
+ "message" : "Expected type `int`; got type `bool` in parameter 1"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 29, 1, 29, 13 ],
+ "message" : "Expected type `int`; got type `` in parameter 1"
+ } ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_class_method_override.py b/src/test/data/pa2/sample/bad_class_method_override.py
new file mode 100644
index 0000000..3f76544
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_class_method_override.py
@@ -0,0 +1,33 @@
+class A(object):
+ def foo(self:"A", x:int) -> int:
+ return x
+
+ def bar(self:"A", x:int) -> int:
+ return x
+
+ def baz(self:"A", x:int) -> int:
+ return x
+
+ def qux(self:"A", x:int) -> int:
+ return x
+
+class B(A):
+
+ # OK override
+ def foo(self:"B", x:int) -> int:
+ return 0
+
+ # Bad override
+ def bar(self:"B") -> int:
+ return 0
+
+ # Bad override
+ def baz(self:"B", x:int) -> bool:
+ return True
+
+ # Bad override
+ def qux(self:"B", x:bool) -> int:
+ return 0
+
+B()
+
diff --git a/src/test/data/pa2/sample/bad_class_method_override.py.ast b/src/test/data/pa2/sample/bad_class_method_override.py.ast
new file mode 100644
index 0000000..e82a758
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_class_method_override.py.ast
@@ -0,0 +1,439 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 32, 4 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 1, 1, 14, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 7, 1, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "FuncDef",
+ "location" : [ 2, 5, 3, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 9, 2, 11 ],
+ "name" : "foo"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 2, 13, 2, 20 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 13, 2, 16 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 18, 2, 20 ],
+ "className" : "A"
+ }
+ }, {
+ "kind" : "TypedVar",
+ "location" : [ 2, 23, 2, 27 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 23, 2, 23 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 25, 2, 27 ],
+ "className" : "int"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 33, 2, 35 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 3, 9, 3, 16 ],
+ "value" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 16, 3, 16 ],
+ "name" : "x"
+ }
+ } ]
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 5, 5, 6, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 9, 5, 11 ],
+ "name" : "bar"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 5, 13, 5, 20 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 13, 5, 16 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 18, 5, 20 ],
+ "className" : "A"
+ }
+ }, {
+ "kind" : "TypedVar",
+ "location" : [ 5, 23, 5, 27 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 23, 5, 23 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 25, 5, 27 ],
+ "className" : "int"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 33, 5, 35 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 6, 9, 6, 16 ],
+ "value" : {
+ "kind" : "Identifier",
+ "location" : [ 6, 16, 6, 16 ],
+ "name" : "x"
+ }
+ } ]
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 8, 5, 9, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 9, 8, 11 ],
+ "name" : "baz"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 8, 13, 8, 20 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 13, 8, 16 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 8, 18, 8, 20 ],
+ "className" : "A"
+ }
+ }, {
+ "kind" : "TypedVar",
+ "location" : [ 8, 23, 8, 27 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 23, 8, 23 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 8, 25, 8, 27 ],
+ "className" : "int"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 8, 33, 8, 35 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 9, 9, 9, 16 ],
+ "value" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 16, 9, 16 ],
+ "name" : "x"
+ }
+ } ]
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 11, 5, 12, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 9, 11, 11 ],
+ "name" : "qux"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 11, 13, 11, 20 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 13, 11, 16 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 11, 18, 11, 20 ],
+ "className" : "A"
+ }
+ }, {
+ "kind" : "TypedVar",
+ "location" : [ 11, 23, 11, 27 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 23, 11, 23 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 11, 25, 11, 27 ],
+ "className" : "int"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 11, 33, 11, 35 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 12, 9, 12, 16 ],
+ "value" : {
+ "kind" : "Identifier",
+ "location" : [ 12, 16, 12, 16 ],
+ "name" : "x"
+ }
+ } ]
+ } ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 14, 1, 32, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 14, 7, 14, 7 ],
+ "name" : "B"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 14, 9, 14, 9 ],
+ "name" : "A"
+ },
+ "declarations" : [ {
+ "kind" : "FuncDef",
+ "location" : [ 17, 5, 18, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 17, 9, 17, 11 ],
+ "name" : "foo"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 17, 13, 17, 20 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 17, 13, 17, 16 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 17, 18, 17, 20 ],
+ "className" : "B"
+ }
+ }, {
+ "kind" : "TypedVar",
+ "location" : [ 17, 23, 17, 27 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 17, 23, 17, 23 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 17, 25, 17, 27 ],
+ "className" : "int"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 17, 33, 17, 35 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 18, 9, 18, 16 ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 18, 16, 18, 16 ],
+ "value" : 0
+ }
+ } ]
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 21, 5, 22, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 21, 9, 21, 11 ],
+ "name" : "bar"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 21, 13, 21, 20 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 21, 13, 21, 16 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 21, 18, 21, 20 ],
+ "className" : "B"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 21, 26, 21, 28 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 22, 9, 22, 16 ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 22, 16, 22, 16 ],
+ "value" : 0
+ }
+ } ]
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 25, 5, 26, 20 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 25, 9, 25, 11 ],
+ "name" : "baz"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 25, 13, 25, 20 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 25, 13, 25, 16 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 25, 18, 25, 20 ],
+ "className" : "B"
+ }
+ }, {
+ "kind" : "TypedVar",
+ "location" : [ 25, 23, 25, 27 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 25, 23, 25, 23 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 25, 25, 25, 27 ],
+ "className" : "int"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 25, 33, 25, 36 ],
+ "className" : "bool"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 26, 9, 26, 19 ],
+ "value" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 26, 16, 26, 19 ],
+ "value" : true
+ }
+ } ]
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 29, 5, 30, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 29, 9, 29, 11 ],
+ "name" : "qux"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 29, 13, 29, 20 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 29, 13, 29, 16 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 29, 18, 29, 20 ],
+ "className" : "B"
+ }
+ }, {
+ "kind" : "TypedVar",
+ "location" : [ 29, 23, 29, 28 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 29, 23, 29, 23 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 29, 25, 29, 28 ],
+ "className" : "bool"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 29, 34, 29, 36 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 30, 9, 30, 16 ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 30, 16, 30, 16 ],
+ "value" : 0
+ }
+ } ]
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 32, 1, 32, 3 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 32, 1, 32, 3 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 32, 1, 32, 1 ],
+ "name" : "B"
+ },
+ "args" : [ ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_class_method_override.py.ast.typed b/src/test/data/pa2/sample/bad_class_method_override.py.ast.typed
new file mode 100644
index 0000000..68716c5
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_class_method_override.py.ast.typed
@@ -0,0 +1,454 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 32, 4 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 1, 1, 14, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 7, 1, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "FuncDef",
+ "location" : [ 2, 5, 3, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 9, 2, 11 ],
+ "name" : "foo"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 2, 13, 2, 20 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 13, 2, 16 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 18, 2, 20 ],
+ "className" : "A"
+ }
+ }, {
+ "kind" : "TypedVar",
+ "location" : [ 2, 23, 2, 27 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 23, 2, 23 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 25, 2, 27 ],
+ "className" : "int"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 33, 2, 35 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 3, 9, 3, 16 ],
+ "value" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 16, 3, 16 ],
+ "name" : "x"
+ }
+ } ]
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 5, 5, 6, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 9, 5, 11 ],
+ "name" : "bar"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 5, 13, 5, 20 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 13, 5, 16 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 18, 5, 20 ],
+ "className" : "A"
+ }
+ }, {
+ "kind" : "TypedVar",
+ "location" : [ 5, 23, 5, 27 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 23, 5, 23 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 25, 5, 27 ],
+ "className" : "int"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 33, 5, 35 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 6, 9, 6, 16 ],
+ "value" : {
+ "kind" : "Identifier",
+ "location" : [ 6, 16, 6, 16 ],
+ "name" : "x"
+ }
+ } ]
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 8, 5, 9, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 9, 8, 11 ],
+ "name" : "baz"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 8, 13, 8, 20 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 13, 8, 16 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 8, 18, 8, 20 ],
+ "className" : "A"
+ }
+ }, {
+ "kind" : "TypedVar",
+ "location" : [ 8, 23, 8, 27 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 23, 8, 23 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 8, 25, 8, 27 ],
+ "className" : "int"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 8, 33, 8, 35 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 9, 9, 9, 16 ],
+ "value" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 16, 9, 16 ],
+ "name" : "x"
+ }
+ } ]
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 11, 5, 12, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 9, 11, 11 ],
+ "name" : "qux"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 11, 13, 11, 20 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 13, 11, 16 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 11, 18, 11, 20 ],
+ "className" : "A"
+ }
+ }, {
+ "kind" : "TypedVar",
+ "location" : [ 11, 23, 11, 27 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 23, 11, 23 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 11, 25, 11, 27 ],
+ "className" : "int"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 11, 33, 11, 35 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 12, 9, 12, 16 ],
+ "value" : {
+ "kind" : "Identifier",
+ "location" : [ 12, 16, 12, 16 ],
+ "name" : "x"
+ }
+ } ]
+ } ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 14, 1, 32, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 14, 7, 14, 7 ],
+ "name" : "B"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 14, 9, 14, 9 ],
+ "name" : "A"
+ },
+ "declarations" : [ {
+ "kind" : "FuncDef",
+ "location" : [ 17, 5, 18, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 17, 9, 17, 11 ],
+ "name" : "foo"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 17, 13, 17, 20 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 17, 13, 17, 16 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 17, 18, 17, 20 ],
+ "className" : "B"
+ }
+ }, {
+ "kind" : "TypedVar",
+ "location" : [ 17, 23, 17, 27 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 17, 23, 17, 23 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 17, 25, 17, 27 ],
+ "className" : "int"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 17, 33, 17, 35 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 18, 9, 18, 16 ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 18, 16, 18, 16 ],
+ "value" : 0
+ }
+ } ]
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 21, 5, 22, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 21, 9, 21, 11 ],
+ "errorMsg" : "Method overridden with different type signature: bar",
+ "name" : "bar"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 21, 13, 21, 20 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 21, 13, 21, 16 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 21, 18, 21, 20 ],
+ "className" : "B"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 21, 26, 21, 28 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 22, 9, 22, 16 ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 22, 16, 22, 16 ],
+ "value" : 0
+ }
+ } ]
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 25, 5, 26, 20 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 25, 9, 25, 11 ],
+ "errorMsg" : "Method overridden with different type signature: baz",
+ "name" : "baz"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 25, 13, 25, 20 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 25, 13, 25, 16 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 25, 18, 25, 20 ],
+ "className" : "B"
+ }
+ }, {
+ "kind" : "TypedVar",
+ "location" : [ 25, 23, 25, 27 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 25, 23, 25, 23 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 25, 25, 25, 27 ],
+ "className" : "int"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 25, 33, 25, 36 ],
+ "className" : "bool"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 26, 9, 26, 19 ],
+ "value" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 26, 16, 26, 19 ],
+ "value" : true
+ }
+ } ]
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 29, 5, 30, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 29, 9, 29, 11 ],
+ "errorMsg" : "Method overridden with different type signature: qux",
+ "name" : "qux"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 29, 13, 29, 20 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 29, 13, 29, 16 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 29, 18, 29, 20 ],
+ "className" : "B"
+ }
+ }, {
+ "kind" : "TypedVar",
+ "location" : [ 29, 23, 29, 28 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 29, 23, 29, 23 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 29, 25, 29, 28 ],
+ "className" : "bool"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 29, 34, 29, 36 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 30, 9, 30, 16 ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 30, 16, 30, 16 ],
+ "value" : 0
+ }
+ } ]
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 32, 1, 32, 3 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 32, 1, 32, 3 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 32, 1, 32, 1 ],
+ "name" : "B"
+ },
+ "args" : [ ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ {
+ "kind" : "CompilerError",
+ "location" : [ 21, 9, 21, 11 ],
+ "message" : "Method overridden with different type signature: bar"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 25, 9, 25, 11 ],
+ "message" : "Method overridden with different type signature: baz"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 29, 9, 29, 11 ],
+ "message" : "Method overridden with different type signature: qux"
+ } ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_class_method_override_attr.py b/src/test/data/pa2/sample/bad_class_method_override_attr.py
new file mode 100644
index 0000000..52c01bd
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_class_method_override_attr.py
@@ -0,0 +1,8 @@
+class A(object):
+ f:int = 3
+
+class B(A):
+ def f(self:B) -> int:
+ return 3
+
+A()
diff --git a/src/test/data/pa2/sample/bad_class_method_override_attr.py.ast b/src/test/data/pa2/sample/bad_class_method_override_attr.py.ast
new file mode 100644
index 0000000..1574d53
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_class_method_override_attr.py.ast
@@ -0,0 +1,111 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 8, 4 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 1, 1, 2, 11 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 7, 1, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 2, 2, 2, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 2, 2, 6 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 2, 2, 2 ],
+ "name" : "f"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 4, 2, 6 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 10, 2, 10 ],
+ "value" : 3
+ }
+ } ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 4, 1, 8, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 7, 4, 7 ],
+ "name" : "B"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 9, 4, 9 ],
+ "name" : "A"
+ },
+ "declarations" : [ {
+ "kind" : "FuncDef",
+ "location" : [ 5, 2, 6, 11 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 6, 5, 6 ],
+ "name" : "f"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 5, 8, 5, 13 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 8, 5, 11 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 13, 5, 13 ],
+ "className" : "B"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 19, 5, 21 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 6, 3, 6, 10 ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 10, 6, 10 ],
+ "value" : 3
+ }
+ } ]
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 8, 1, 8, 3 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 8, 1, 8, 3 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 1, 8, 1 ],
+ "name" : "A"
+ },
+ "args" : [ ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_class_method_override_attr.py.ast.typed b/src/test/data/pa2/sample/bad_class_method_override_attr.py.ast.typed
new file mode 100644
index 0000000..fcfb779
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_class_method_override_attr.py.ast.typed
@@ -0,0 +1,116 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 8, 4 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 1, 1, 2, 11 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 7, 1, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 2, 2, 2, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 2, 2, 6 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 2, 2, 2 ],
+ "name" : "f"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 4, 2, 6 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 10, 2, 10 ],
+ "value" : 3
+ }
+ } ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 4, 1, 8, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 7, 4, 7 ],
+ "name" : "B"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 9, 4, 9 ],
+ "name" : "A"
+ },
+ "declarations" : [ {
+ "kind" : "FuncDef",
+ "location" : [ 5, 2, 6, 11 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 6, 5, 6 ],
+ "errorMsg" : "Cannot re-define attribute: f",
+ "name" : "f"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 5, 8, 5, 13 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 8, 5, 11 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 13, 5, 13 ],
+ "className" : "B"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 19, 5, 21 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 6, 3, 6, 10 ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 10, 6, 10 ],
+ "value" : 3
+ }
+ } ]
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 8, 1, 8, 3 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 8, 1, 8, 3 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 1, 8, 1 ],
+ "name" : "A"
+ },
+ "args" : [ ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ {
+ "kind" : "CompilerError",
+ "location" : [ 5, 6, 5, 6 ],
+ "message" : "Cannot re-define attribute: f"
+ } ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_class_super.py b/src/test/data/pa2/sample/bad_class_super.py
new file mode 100644
index 0000000..9701776
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_class_super.py
@@ -0,0 +1,15 @@
+# Super is not defined
+class A(B):
+ x:int = 1
+
+z:int = 2
+
+# Super is not a class
+class B(z):
+ x:int = 1
+
+# Cannot extend special classes
+class C(int):
+ x:int = 1
+
+A()
diff --git a/src/test/data/pa2/sample/bad_class_super.py.ast b/src/test/data/pa2/sample/bad_class_super.py.ast
new file mode 100644
index 0000000..4aed62a
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_class_super.py.ast
@@ -0,0 +1,154 @@
+{
+ "kind" : "Program",
+ "location" : [ 2, 1, 15, 4 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 2, 1, 3, 14 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 7, 2, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 9, 2, 9 ],
+ "name" : "B"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 3, 5, 3, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 3, 5, 3, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 5, 3, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 3, 7, 3, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 3, 13, 3, 13 ],
+ "value" : 1
+ }
+ } ]
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 5, 1, 5, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 5, 1, 5, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 1, 5, 1 ],
+ "name" : "z"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 3, 5, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 5, 9, 5, 9 ],
+ "value" : 2
+ }
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 8, 1, 9, 14 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 7, 8, 7 ],
+ "name" : "B"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 9, 8, 9 ],
+ "name" : "z"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 9, 5, 9, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 9, 5, 9, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 5, 9, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 9, 7, 9, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 9, 13, 9, 13 ],
+ "value" : 1
+ }
+ } ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 12, 1, 13, 14 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 12, 7, 12, 7 ],
+ "name" : "C"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 12, 9, 12, 11 ],
+ "name" : "int"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 13, 5, 13, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 13, 5, 13, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 13, 5, 13, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 13, 7, 13, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 13, 13, 13, 13 ],
+ "value" : 1
+ }
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 15, 1, 15, 3 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 15, 1, 15, 3 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 15, 1, 15, 1 ],
+ "name" : "A"
+ },
+ "args" : [ ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_class_super.py.ast.typed b/src/test/data/pa2/sample/bad_class_super.py.ast.typed
new file mode 100644
index 0000000..128383f
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_class_super.py.ast.typed
@@ -0,0 +1,169 @@
+{
+ "kind" : "Program",
+ "location" : [ 2, 1, 15, 4 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 2, 1, 3, 14 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 7, 2, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 9, 2, 9 ],
+ "errorMsg" : "Super-class not defined: B",
+ "name" : "B"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 3, 5, 3, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 3, 5, 3, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 5, 3, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 3, 7, 3, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 3, 13, 3, 13 ],
+ "value" : 1
+ }
+ } ]
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 5, 1, 5, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 5, 1, 5, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 1, 5, 1 ],
+ "name" : "z"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 3, 5, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 5, 9, 5, 9 ],
+ "value" : 2
+ }
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 8, 1, 9, 14 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 7, 8, 7 ],
+ "name" : "B"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 9, 8, 9 ],
+ "errorMsg" : "Super-class must be a class: z",
+ "name" : "z"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 9, 5, 9, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 9, 5, 9, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 5, 9, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 9, 7, 9, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 9, 13, 9, 13 ],
+ "value" : 1
+ }
+ } ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 12, 1, 13, 14 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 12, 7, 12, 7 ],
+ "name" : "C"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 12, 9, 12, 11 ],
+ "errorMsg" : "Cannot extend special class: int",
+ "name" : "int"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 13, 5, 13, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 13, 5, 13, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 13, 5, 13, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 13, 7, 13, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 13, 13, 13, 13 ],
+ "value" : 1
+ }
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 15, 1, 15, 3 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 15, 1, 15, 3 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 15, 1, 15, 1 ],
+ "name" : "A"
+ },
+ "args" : [ ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ {
+ "kind" : "CompilerError",
+ "location" : [ 2, 9, 2, 9 ],
+ "message" : "Super-class not defined: B"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 8, 9, 8, 9 ],
+ "message" : "Super-class must be a class: z"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 12, 9, 12, 11 ],
+ "message" : "Cannot extend special class: int"
+ } ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_concat.py b/src/test/data/pa2/sample/bad_concat.py
new file mode 100644
index 0000000..56e7802
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_concat.py
@@ -0,0 +1,3 @@
+"Hello" + ["World"]
+1 + [2]
+[] + [1]
diff --git a/src/test/data/pa2/sample/bad_concat.py.ast b/src/test/data/pa2/sample/bad_concat.py.ast
new file mode 100644
index 0000000..0fdfbd6
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_concat.py.ast
@@ -0,0 +1,77 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 3, 9 ],
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 1, 1, 1, 19 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 1, 1, 1, 19 ],
+ "left" : {
+ "kind" : "StringLiteral",
+ "location" : [ 1, 1, 1, 7 ],
+ "value" : "Hello"
+ },
+ "operator" : "+",
+ "right" : {
+ "kind" : "ListExpr",
+ "location" : [ 1, 11, 1, 19 ],
+ "elements" : [ {
+ "kind" : "StringLiteral",
+ "location" : [ 1, 12, 1, 18 ],
+ "value" : "World"
+ } ]
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 2, 1, 2, 7 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 2, 1, 2, 7 ],
+ "left" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 1, 2, 1 ],
+ "value" : 1
+ },
+ "operator" : "+",
+ "right" : {
+ "kind" : "ListExpr",
+ "location" : [ 2, 5, 2, 7 ],
+ "elements" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 6, 2, 6 ],
+ "value" : 2
+ } ]
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 3, 1, 3, 8 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 3, 1, 3, 8 ],
+ "left" : {
+ "kind" : "ListExpr",
+ "location" : [ 3, 1, 3, 2 ],
+ "elements" : [ ]
+ },
+ "operator" : "+",
+ "right" : {
+ "kind" : "ListExpr",
+ "location" : [ 3, 6, 3, 8 ],
+ "elements" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 3, 7, 3, 7 ],
+ "value" : 1
+ } ]
+ }
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_concat.py.ast.typed b/src/test/data/pa2/sample/bad_concat.py.ast.typed
new file mode 100644
index 0000000..60f5b0c
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_concat.py.ast.typed
@@ -0,0 +1,149 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 3, 9 ],
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 1, 1, 1, 19 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 1, 1, 1, 19 ],
+ "errorMsg" : "Cannot apply operator `+` on types `str` and `[str]`",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ },
+ "left" : {
+ "kind" : "StringLiteral",
+ "location" : [ 1, 1, 1, 7 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "value" : "Hello"
+ },
+ "operator" : "+",
+ "right" : {
+ "kind" : "ListExpr",
+ "location" : [ 1, 11, 1, 19 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ }
+ },
+ "elements" : [ {
+ "kind" : "StringLiteral",
+ "location" : [ 1, 12, 1, 18 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "value" : "World"
+ } ]
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 2, 1, 2, 7 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 2, 1, 2, 7 ],
+ "errorMsg" : "Cannot apply operator `+` on types `int` and `[int]`",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "left" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 1, 2, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ },
+ "operator" : "+",
+ "right" : {
+ "kind" : "ListExpr",
+ "location" : [ 2, 5, 2, 7 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "elements" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 6, 2, 6 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 2
+ } ]
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 3, 1, 3, 8 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 3, 1, 3, 8 ],
+ "errorMsg" : "Cannot apply operator `+` on types `` and `[int]`",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ },
+ "left" : {
+ "kind" : "ListExpr",
+ "location" : [ 3, 1, 3, 2 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ },
+ "elements" : [ ]
+ },
+ "operator" : "+",
+ "right" : {
+ "kind" : "ListExpr",
+ "location" : [ 3, 6, 3, 8 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "elements" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 3, 7, 3, 7 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ } ]
+ }
+ }
+ } ],
+ "errors" : {
+ "errors" : [ {
+ "kind" : "CompilerError",
+ "location" : [ 1, 1, 1, 19 ],
+ "message" : "Cannot apply operator `+` on types `str` and `[str]`"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 2, 1, 2, 7 ],
+ "message" : "Cannot apply operator `+` on types `int` and `[int]`"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 3, 1, 3, 8 ],
+ "message" : "Cannot apply operator `+` on types `` and `[int]`"
+ } ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_duplicate_class.py b/src/test/data/pa2/sample/bad_duplicate_class.py
new file mode 100644
index 0000000..8f8dd05
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_duplicate_class.py
@@ -0,0 +1,18 @@
+class A(object):
+ x:int = 1
+
+z:bool = True
+
+# Duplicate
+class A(object):
+ x:int = 1
+
+# Duplicate
+class str(object):
+ x:int = 1
+
+# Duplicate
+class z(object):
+ x:int = 1
+
+A()
diff --git a/src/test/data/pa2/sample/bad_duplicate_class.py.ast b/src/test/data/pa2/sample/bad_duplicate_class.py.ast
new file mode 100644
index 0000000..547360b
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_duplicate_class.py.ast
@@ -0,0 +1,190 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 18, 4 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 1, 1, 2, 14 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 7, 1, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 2, 5, 2, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 5, 2, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 5, 2, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 7, 2, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 13, 2, 13 ],
+ "value" : 1
+ }
+ } ]
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 4, 1, 4, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 4, 1, 4, 6 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 1, 4, 1 ],
+ "name" : "z"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 3, 4, 6 ],
+ "className" : "bool"
+ }
+ },
+ "value" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 4, 10, 4, 13 ],
+ "value" : true
+ }
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 7, 1, 8, 14 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 7, 7, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 9, 7, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 8, 5, 8, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 8, 5, 8, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 5, 8, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 8, 7, 8, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 8, 13, 8, 13 ],
+ "value" : 1
+ }
+ } ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 11, 1, 12, 14 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 7, 11, 9 ],
+ "name" : "str"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 11, 11, 16 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 12, 5, 12, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 12, 5, 12, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 12, 5, 12, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 12, 7, 12, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 12, 13, 12, 13 ],
+ "value" : 1
+ }
+ } ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 15, 1, 16, 14 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 15, 7, 15, 7 ],
+ "name" : "z"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 15, 9, 15, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 16, 5, 16, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 16, 5, 16, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 16, 5, 16, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 16, 7, 16, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 16, 13, 16, 13 ],
+ "value" : 1
+ }
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 18, 1, 18, 3 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 18, 1, 18, 3 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 18, 1, 18, 1 ],
+ "name" : "A"
+ },
+ "args" : [ ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_duplicate_class.py.ast.typed b/src/test/data/pa2/sample/bad_duplicate_class.py.ast.typed
new file mode 100644
index 0000000..3791ada
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_duplicate_class.py.ast.typed
@@ -0,0 +1,205 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 18, 4 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 1, 1, 2, 14 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 7, 1, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 2, 5, 2, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 5, 2, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 5, 2, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 7, 2, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 13, 2, 13 ],
+ "value" : 1
+ }
+ } ]
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 4, 1, 4, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 4, 1, 4, 6 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 1, 4, 1 ],
+ "name" : "z"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 3, 4, 6 ],
+ "className" : "bool"
+ }
+ },
+ "value" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 4, 10, 4, 13 ],
+ "value" : true
+ }
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 7, 1, 8, 14 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 7, 7, 7 ],
+ "errorMsg" : "Duplicate declaration of identifier in same scope: A",
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 9, 7, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 8, 5, 8, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 8, 5, 8, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 5, 8, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 8, 7, 8, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 8, 13, 8, 13 ],
+ "value" : 1
+ }
+ } ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 11, 1, 12, 14 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 7, 11, 9 ],
+ "errorMsg" : "Duplicate declaration of identifier in same scope: str",
+ "name" : "str"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 11, 11, 16 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 12, 5, 12, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 12, 5, 12, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 12, 5, 12, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 12, 7, 12, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 12, 13, 12, 13 ],
+ "value" : 1
+ }
+ } ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 15, 1, 16, 14 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 15, 7, 15, 7 ],
+ "errorMsg" : "Duplicate declaration of identifier in same scope: z",
+ "name" : "z"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 15, 9, 15, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 16, 5, 16, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 16, 5, 16, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 16, 5, 16, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 16, 7, 16, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 16, 13, 16, 13 ],
+ "value" : 1
+ }
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 18, 1, 18, 3 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 18, 1, 18, 3 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 18, 1, 18, 1 ],
+ "name" : "A"
+ },
+ "args" : [ ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ {
+ "kind" : "CompilerError",
+ "location" : [ 7, 7, 7, 7 ],
+ "message" : "Duplicate declaration of identifier in same scope: A"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 11, 7, 11, 9 ],
+ "message" : "Duplicate declaration of identifier in same scope: str"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 15, 7, 15, 7 ],
+ "message" : "Duplicate declaration of identifier in same scope: z"
+ } ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_duplicate_class_member.py b/src/test/data/pa2/sample/bad_duplicate_class_member.py
new file mode 100644
index 0000000..7a5026f
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_duplicate_class_member.py
@@ -0,0 +1,12 @@
+class A(object):
+ x:int = 1 # OK
+
+ def foo(self: "A") -> int: # OK
+ return 0
+
+ x:int = 1 # Duplicate
+
+ def foo(self: "A") -> int: # Duplicate
+ return 0
+
+A()
diff --git a/src/test/data/pa2/sample/bad_duplicate_class_member.py.ast b/src/test/data/pa2/sample/bad_duplicate_class_member.py.ast
new file mode 100644
index 0000000..58b0ddb
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_duplicate_class_member.py.ast
@@ -0,0 +1,156 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 12, 4 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 1, 1, 12, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 7, 1, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 2, 5, 2, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 5, 2, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 5, 2, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 7, 2, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 13, 2, 13 ],
+ "value" : 1
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 4, 5, 5, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 9, 4, 11 ],
+ "name" : "foo"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 4, 13, 4, 21 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 13, 4, 16 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 19, 4, 21 ],
+ "className" : "A"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 27, 4, 29 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 5, 9, 5, 16 ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 5, 16, 5, 16 ],
+ "value" : 0
+ }
+ } ]
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 7, 5, 7, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 7, 5, 7, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 5, 7, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 7, 7, 7, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 7, 13, 7, 13 ],
+ "value" : 1
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 9, 5, 10, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 9, 9, 11 ],
+ "name" : "foo"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 9, 13, 9, 21 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 13, 9, 16 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 9, 19, 9, 21 ],
+ "className" : "A"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 9, 27, 9, 29 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 10, 9, 10, 16 ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 10, 16, 10, 16 ],
+ "value" : 0
+ }
+ } ]
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 12, 1, 12, 3 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 12, 1, 12, 3 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 12, 1, 12, 1 ],
+ "name" : "A"
+ },
+ "args" : [ ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_duplicate_class_member.py.ast.typed b/src/test/data/pa2/sample/bad_duplicate_class_member.py.ast.typed
new file mode 100644
index 0000000..cb97ac4
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_duplicate_class_member.py.ast.typed
@@ -0,0 +1,166 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 12, 4 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 1, 1, 12, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 7, 1, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 2, 5, 2, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 5, 2, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 5, 2, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 7, 2, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 13, 2, 13 ],
+ "value" : 1
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 4, 5, 5, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 9, 4, 11 ],
+ "name" : "foo"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 4, 13, 4, 21 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 13, 4, 16 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 19, 4, 21 ],
+ "className" : "A"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 27, 4, 29 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 5, 9, 5, 16 ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 5, 16, 5, 16 ],
+ "value" : 0
+ }
+ } ]
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 7, 5, 7, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 7, 5, 7, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 5, 7, 5 ],
+ "errorMsg" : "Duplicate declaration of identifier in same scope: x",
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 7, 7, 7, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 7, 13, 7, 13 ],
+ "value" : 1
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 9, 5, 10, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 9, 9, 11 ],
+ "errorMsg" : "Duplicate declaration of identifier in same scope: foo",
+ "name" : "foo"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 9, 13, 9, 21 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 13, 9, 16 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 9, 19, 9, 21 ],
+ "className" : "A"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 9, 27, 9, 29 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 10, 9, 10, 16 ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 10, 16, 10, 16 ],
+ "value" : 0
+ }
+ } ]
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 12, 1, 12, 3 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 12, 1, 12, 3 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 12, 1, 12, 1 ],
+ "name" : "A"
+ },
+ "args" : [ ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ {
+ "kind" : "CompilerError",
+ "location" : [ 7, 5, 7, 5 ],
+ "message" : "Duplicate declaration of identifier in same scope: x"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 9, 9, 9, 11 ],
+ "message" : "Duplicate declaration of identifier in same scope: foo"
+ } ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_duplicate_global.py b/src/test/data/pa2/sample/bad_duplicate_global.py
new file mode 100644
index 0000000..4b293ea
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_duplicate_global.py
@@ -0,0 +1,18 @@
+x:int = 1
+
+def foo() -> object:
+ pass
+
+# `foo` cannot be redefined in the same scope
+def foo() -> object:
+ pass
+
+# `print` cannot be redefined in the same scope
+def print(val:object) -> object:
+ pass
+
+# `x` cannot be redefined in the same scope
+x:int = 2
+
+
+foo()
diff --git a/src/test/data/pa2/sample/bad_duplicate_global.py.ast b/src/test/data/pa2/sample/bad_duplicate_global.py.ast
new file mode 100644
index 0000000..76e6707
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_duplicate_global.py.ast
@@ -0,0 +1,129 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 18, 6 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 3, 1, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 9, 1, 9 ],
+ "value" : 1
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 3, 1, 4, 9 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 5, 3, 7 ],
+ "name" : "foo"
+ },
+ "params" : [ ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 3, 14, 3, 19 ],
+ "className" : "object"
+ },
+ "declarations" : [ ],
+ "statements" : [ ]
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 7, 1, 8, 9 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 5, 7, 7 ],
+ "name" : "foo"
+ },
+ "params" : [ ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 7, 14, 7, 19 ],
+ "className" : "object"
+ },
+ "declarations" : [ ],
+ "statements" : [ ]
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 11, 1, 12, 9 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 5, 11, 9 ],
+ "name" : "print"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 11, 11, 11, 20 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 11, 11, 13 ],
+ "name" : "val"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 11, 15, 11, 20 ],
+ "className" : "object"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 11, 26, 11, 31 ],
+ "className" : "object"
+ },
+ "declarations" : [ ],
+ "statements" : [ ]
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 15, 1, 15, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 15, 1, 15, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 15, 1, 15, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 15, 3, 15, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 15, 9, 15, 9 ],
+ "value" : 2
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 18, 1, 18, 5 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 18, 1, 18, 5 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 18, 1, 18, 3 ],
+ "name" : "foo"
+ },
+ "args" : [ ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_duplicate_global.py.ast.typed b/src/test/data/pa2/sample/bad_duplicate_global.py.ast.typed
new file mode 100644
index 0000000..7d72792
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_duplicate_global.py.ast.typed
@@ -0,0 +1,144 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 18, 6 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 3, 1, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 9, 1, 9 ],
+ "value" : 1
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 3, 1, 4, 9 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 5, 3, 7 ],
+ "name" : "foo"
+ },
+ "params" : [ ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 3, 14, 3, 19 ],
+ "className" : "object"
+ },
+ "declarations" : [ ],
+ "statements" : [ ]
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 7, 1, 8, 9 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 5, 7, 7 ],
+ "errorMsg" : "Duplicate declaration of identifier in same scope: foo",
+ "name" : "foo"
+ },
+ "params" : [ ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 7, 14, 7, 19 ],
+ "className" : "object"
+ },
+ "declarations" : [ ],
+ "statements" : [ ]
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 11, 1, 12, 9 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 5, 11, 9 ],
+ "errorMsg" : "Duplicate declaration of identifier in same scope: print",
+ "name" : "print"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 11, 11, 11, 20 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 11, 11, 13 ],
+ "name" : "val"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 11, 15, 11, 20 ],
+ "className" : "object"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 11, 26, 11, 31 ],
+ "className" : "object"
+ },
+ "declarations" : [ ],
+ "statements" : [ ]
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 15, 1, 15, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 15, 1, 15, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 15, 1, 15, 1 ],
+ "errorMsg" : "Duplicate declaration of identifier in same scope: x",
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 15, 3, 15, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 15, 9, 15, 9 ],
+ "value" : 2
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 18, 1, 18, 5 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 18, 1, 18, 5 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 18, 1, 18, 3 ],
+ "name" : "foo"
+ },
+ "args" : [ ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ {
+ "kind" : "CompilerError",
+ "location" : [ 7, 5, 7, 7 ],
+ "message" : "Duplicate declaration of identifier in same scope: foo"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 11, 5, 11, 9 ],
+ "message" : "Duplicate declaration of identifier in same scope: print"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 15, 1, 15, 1 ],
+ "message" : "Duplicate declaration of identifier in same scope: x"
+ } ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_duplicate_global_2.py b/src/test/data/pa2/sample/bad_duplicate_global_2.py
new file mode 100644
index 0000000..62ee129
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_duplicate_global_2.py
@@ -0,0 +1,6 @@
+class x(object):
+ pass
+
+x:int = 5
+
+pass
diff --git a/src/test/data/pa2/sample/bad_duplicate_global_2.py.ast b/src/test/data/pa2/sample/bad_duplicate_global_2.py.ast
new file mode 100644
index 0000000..c3a5985
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_duplicate_global_2.py.ast
@@ -0,0 +1,47 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 6, 5 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 1, 1, 2, 9 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 7, 1, 7 ],
+ "name" : "x"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ ]
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 4, 1, 4, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 4, 1, 4, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 1, 4, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 3, 4, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 4, 9, 4, 9 ],
+ "value" : 5
+ }
+ } ],
+ "statements" : [ ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_duplicate_global_2.py.ast.typed b/src/test/data/pa2/sample/bad_duplicate_global_2.py.ast.typed
new file mode 100644
index 0000000..506a6ca
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_duplicate_global_2.py.ast.typed
@@ -0,0 +1,52 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 6, 5 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 1, 1, 2, 9 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 7, 1, 7 ],
+ "name" : "x"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ ]
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 4, 1, 4, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 4, 1, 4, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 1, 4, 1 ],
+ "errorMsg" : "Duplicate declaration of identifier in same scope: x",
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 3, 4, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 4, 9, 4, 9 ],
+ "value" : 5
+ }
+ } ],
+ "statements" : [ ],
+ "errors" : {
+ "errors" : [ {
+ "kind" : "CompilerError",
+ "location" : [ 4, 1, 4, 1 ],
+ "message" : "Duplicate declaration of identifier in same scope: x"
+ } ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_duplicate_local.py b/src/test/data/pa2/sample/bad_duplicate_local.py
new file mode 100644
index 0000000..bb25faf
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_duplicate_local.py
@@ -0,0 +1,21 @@
+x:int = 1
+y:int = 2
+z:int = 3
+
+def foo(x:int) -> object:
+ y:int = 4 # OK
+ x:int = 5 # Duplicate declaration
+ global z # OK
+ global y # Duplicate declaration
+
+ def x() -> int: # Duplicate declaration
+ return 0
+
+ pass
+
+def bar(x:int, x:int) -> int: # Duplicate params
+ return x
+
+
+foo(1)
+
diff --git a/src/test/data/pa2/sample/bad_duplicate_local.py.ast b/src/test/data/pa2/sample/bad_duplicate_local.py.ast
new file mode 100644
index 0000000..53f6fad
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_duplicate_local.py.ast
@@ -0,0 +1,257 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 20, 7 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 3, 1, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 9, 1, 9 ],
+ "value" : 1
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 2, 1, 2, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 1, 2, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 1, 2, 1 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 3, 2, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 9, 2, 9 ],
+ "value" : 2
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 3, 1, 3, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 3, 1, 3, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 1, 3, 1 ],
+ "name" : "z"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 3, 3, 3, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 3, 9, 3, 9 ],
+ "value" : 3
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 5, 1, 14, 9 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 5, 5, 7 ],
+ "name" : "foo"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 5, 9, 5, 13 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 9, 5, 9 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 11, 5, 13 ],
+ "className" : "int"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 19, 5, 24 ],
+ "className" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 6, 5, 6, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 6, 5, 6, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 6, 5, 6, 5 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 6, 7, 6, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 13, 6, 13 ],
+ "value" : 4
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 7, 5, 7, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 7, 5, 7, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 5, 7, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 7, 7, 7, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 7, 13, 7, 13 ],
+ "value" : 5
+ }
+ }, {
+ "kind" : "GlobalDecl",
+ "location" : [ 8, 5, 8, 12 ],
+ "variable" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 12, 8, 12 ],
+ "name" : "z"
+ }
+ }, {
+ "kind" : "GlobalDecl",
+ "location" : [ 9, 5, 9, 12 ],
+ "variable" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 12, 9, 12 ],
+ "name" : "y"
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 11, 5, 12, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 9, 11, 9 ],
+ "name" : "x"
+ },
+ "params" : [ ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 11, 16, 11, 18 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 12, 9, 12, 16 ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 12, 16, 12, 16 ],
+ "value" : 0
+ }
+ } ]
+ } ],
+ "statements" : [ ]
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 16, 1, 17, 13 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 16, 5, 16, 7 ],
+ "name" : "bar"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 16, 9, 16, 13 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 16, 9, 16, 9 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 16, 11, 16, 13 ],
+ "className" : "int"
+ }
+ }, {
+ "kind" : "TypedVar",
+ "location" : [ 16, 16, 16, 20 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 16, 16, 16, 16 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 16, 18, 16, 20 ],
+ "className" : "int"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 16, 26, 16, 28 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 17, 5, 17, 12 ],
+ "value" : {
+ "kind" : "Identifier",
+ "location" : [ 17, 12, 17, 12 ],
+ "name" : "x"
+ }
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 20, 1, 20, 6 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 20, 1, 20, 6 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 20, 1, 20, 3 ],
+ "name" : "foo"
+ },
+ "args" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 20, 5, 20, 5 ],
+ "value" : 1
+ } ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_duplicate_local.py.ast.typed b/src/test/data/pa2/sample/bad_duplicate_local.py.ast.typed
new file mode 100644
index 0000000..1559865
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_duplicate_local.py.ast.typed
@@ -0,0 +1,277 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 20, 7 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 3, 1, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 9, 1, 9 ],
+ "value" : 1
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 2, 1, 2, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 1, 2, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 1, 2, 1 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 3, 2, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 9, 2, 9 ],
+ "value" : 2
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 3, 1, 3, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 3, 1, 3, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 1, 3, 1 ],
+ "name" : "z"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 3, 3, 3, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 3, 9, 3, 9 ],
+ "value" : 3
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 5, 1, 14, 9 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 5, 5, 7 ],
+ "name" : "foo"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 5, 9, 5, 13 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 9, 5, 9 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 11, 5, 13 ],
+ "className" : "int"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 19, 5, 24 ],
+ "className" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 6, 5, 6, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 6, 5, 6, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 6, 5, 6, 5 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 6, 7, 6, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 13, 6, 13 ],
+ "value" : 4
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 7, 5, 7, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 7, 5, 7, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 5, 7, 5 ],
+ "errorMsg" : "Duplicate declaration of identifier in same scope: x",
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 7, 7, 7, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 7, 13, 7, 13 ],
+ "value" : 5
+ }
+ }, {
+ "kind" : "GlobalDecl",
+ "location" : [ 8, 5, 8, 12 ],
+ "variable" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 12, 8, 12 ],
+ "name" : "z"
+ }
+ }, {
+ "kind" : "GlobalDecl",
+ "location" : [ 9, 5, 9, 12 ],
+ "variable" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 12, 9, 12 ],
+ "errorMsg" : "Duplicate declaration of identifier in same scope: y",
+ "name" : "y"
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 11, 5, 12, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 9, 11, 9 ],
+ "errorMsg" : "Duplicate declaration of identifier in same scope: x",
+ "name" : "x"
+ },
+ "params" : [ ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 11, 16, 11, 18 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 12, 9, 12, 16 ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 12, 16, 12, 16 ],
+ "value" : 0
+ }
+ } ]
+ } ],
+ "statements" : [ ]
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 16, 1, 17, 13 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 16, 5, 16, 7 ],
+ "name" : "bar"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 16, 9, 16, 13 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 16, 9, 16, 9 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 16, 11, 16, 13 ],
+ "className" : "int"
+ }
+ }, {
+ "kind" : "TypedVar",
+ "location" : [ 16, 16, 16, 20 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 16, 16, 16, 16 ],
+ "errorMsg" : "Duplicate declaration of identifier in same scope: x",
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 16, 18, 16, 20 ],
+ "className" : "int"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 16, 26, 16, 28 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 17, 5, 17, 12 ],
+ "value" : {
+ "kind" : "Identifier",
+ "location" : [ 17, 12, 17, 12 ],
+ "name" : "x"
+ }
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 20, 1, 20, 6 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 20, 1, 20, 6 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 20, 1, 20, 3 ],
+ "name" : "foo"
+ },
+ "args" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 20, 5, 20, 5 ],
+ "value" : 1
+ } ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ {
+ "kind" : "CompilerError",
+ "location" : [ 7, 5, 7, 5 ],
+ "message" : "Duplicate declaration of identifier in same scope: x"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 9, 12, 9, 12 ],
+ "message" : "Duplicate declaration of identifier in same scope: y"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 11, 9, 11, 9 ],
+ "message" : "Duplicate declaration of identifier in same scope: x"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 16, 16, 16, 16 ],
+ "message" : "Duplicate declaration of identifier in same scope: x"
+ } ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_expr_binary.py b/src/test/data/pa2/sample/bad_expr_binary.py
new file mode 100644
index 0000000..1668849
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_expr_binary.py
@@ -0,0 +1,13 @@
+1 and 2
+1 or 2
+True - False
+True < False
+1 + True
+False + 0
+1 == True
+False != 0
+1 is 1
+True is False
+None + None
+None == None
+None is None
diff --git a/src/test/data/pa2/sample/bad_expr_binary.py.ast b/src/test/data/pa2/sample/bad_expr_binary.py.ast
new file mode 100644
index 0000000..c55893a
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_expr_binary.py.ast
@@ -0,0 +1,239 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 13, 13 ],
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 1, 1, 1, 7 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 1, 1, 1, 7 ],
+ "left" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 1, 1, 1 ],
+ "value" : 1
+ },
+ "operator" : "and",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 7, 1, 7 ],
+ "value" : 2
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 2, 1, 2, 6 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 2, 1, 2, 6 ],
+ "left" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 1, 2, 1 ],
+ "value" : 1
+ },
+ "operator" : "or",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 6, 2, 6 ],
+ "value" : 2
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 3, 1, 3, 12 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 3, 1, 3, 12 ],
+ "left" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 3, 1, 3, 4 ],
+ "value" : true
+ },
+ "operator" : "-",
+ "right" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 3, 8, 3, 12 ],
+ "value" : false
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 4, 1, 4, 12 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 4, 1, 4, 12 ],
+ "left" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 4, 1, 4, 4 ],
+ "value" : true
+ },
+ "operator" : "<",
+ "right" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 4, 8, 4, 12 ],
+ "value" : false
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 5, 1, 5, 8 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 5, 1, 5, 8 ],
+ "left" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 5, 1, 5, 1 ],
+ "value" : 1
+ },
+ "operator" : "+",
+ "right" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 5, 5, 5, 8 ],
+ "value" : true
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 6, 1, 6, 9 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 6, 1, 6, 9 ],
+ "left" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 6, 1, 6, 5 ],
+ "value" : false
+ },
+ "operator" : "+",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 9, 6, 9 ],
+ "value" : 0
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 7, 1, 7, 9 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 7, 1, 7, 9 ],
+ "left" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 7, 1, 7, 1 ],
+ "value" : 1
+ },
+ "operator" : "==",
+ "right" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 7, 6, 7, 9 ],
+ "value" : true
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 8, 1, 8, 10 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 8, 1, 8, 10 ],
+ "left" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 8, 1, 8, 5 ],
+ "value" : false
+ },
+ "operator" : "!=",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 8, 10, 8, 10 ],
+ "value" : 0
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 9, 1, 9, 6 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 9, 1, 9, 6 ],
+ "left" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 9, 1, 9, 1 ],
+ "value" : 1
+ },
+ "operator" : "is",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 9, 6, 9, 6 ],
+ "value" : 1
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 10, 1, 10, 13 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 10, 1, 10, 13 ],
+ "left" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 10, 1, 10, 4 ],
+ "value" : true
+ },
+ "operator" : "is",
+ "right" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 10, 9, 10, 13 ],
+ "value" : false
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 11, 1, 11, 11 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 11, 1, 11, 11 ],
+ "left" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 11, 1, 11, 4 ]
+ },
+ "operator" : "+",
+ "right" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 11, 8, 11, 11 ]
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 12, 1, 12, 12 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 12, 1, 12, 12 ],
+ "left" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 12, 1, 12, 4 ]
+ },
+ "operator" : "==",
+ "right" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 12, 9, 12, 12 ]
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 13, 1, 13, 12 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 13, 1, 13, 12 ],
+ "left" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 13, 1, 13, 4 ]
+ },
+ "operator" : "is",
+ "right" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 13, 9, 13, 12 ]
+ }
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_expr_binary.py.ast.typed b/src/test/data/pa2/sample/bad_expr_binary.py.ast.typed
new file mode 100644
index 0000000..851cc92
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_expr_binary.py.ast.typed
@@ -0,0 +1,455 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 13, 13 ],
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 1, 1, 1, 7 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 1, 1, 1, 7 ],
+ "errorMsg" : "Cannot apply operator `and` on types `int` and `int`",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "left" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 1, 1, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ },
+ "operator" : "and",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 7, 1, 7 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 2
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 2, 1, 2, 6 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 2, 1, 2, 6 ],
+ "errorMsg" : "Cannot apply operator `or` on types `int` and `int`",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "left" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 1, 2, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ },
+ "operator" : "or",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 6, 2, 6 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 2
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 3, 1, 3, 12 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 3, 1, 3, 12 ],
+ "errorMsg" : "Cannot apply operator `-` on types `bool` and `bool`",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "left" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 3, 1, 3, 4 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : true
+ },
+ "operator" : "-",
+ "right" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 3, 8, 3, 12 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : false
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 4, 1, 4, 12 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 4, 1, 4, 12 ],
+ "errorMsg" : "Cannot apply operator `<` on types `bool` and `bool`",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "left" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 4, 1, 4, 4 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : true
+ },
+ "operator" : "<",
+ "right" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 4, 8, 4, 12 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : false
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 5, 1, 5, 8 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 5, 1, 5, 8 ],
+ "errorMsg" : "Cannot apply operator `+` on types `int` and `bool`",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "left" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 5, 1, 5, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ },
+ "operator" : "+",
+ "right" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 5, 5, 5, 8 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : true
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 6, 1, 6, 9 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 6, 1, 6, 9 ],
+ "errorMsg" : "Cannot apply operator `+` on types `bool` and `int`",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "left" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 6, 1, 6, 5 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : false
+ },
+ "operator" : "+",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 9, 6, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 0
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 7, 1, 7, 9 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 7, 1, 7, 9 ],
+ "errorMsg" : "Cannot apply operator `==` on types `int` and `bool`",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "left" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 7, 1, 7, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ },
+ "operator" : "==",
+ "right" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 7, 6, 7, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : true
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 8, 1, 8, 10 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 8, 1, 8, 10 ],
+ "errorMsg" : "Cannot apply operator `!=` on types `bool` and `int`",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "left" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 8, 1, 8, 5 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : false
+ },
+ "operator" : "!=",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 8, 10, 8, 10 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 0
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 9, 1, 9, 6 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 9, 1, 9, 6 ],
+ "errorMsg" : "Cannot apply operator `is` on types `int` and `int`",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "left" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 9, 1, 9, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ },
+ "operator" : "is",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 9, 6, 9, 6 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 10, 1, 10, 13 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 10, 1, 10, 13 ],
+ "errorMsg" : "Cannot apply operator `is` on types `bool` and `bool`",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "left" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 10, 1, 10, 4 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : true
+ },
+ "operator" : "is",
+ "right" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 10, 9, 10, 13 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : false
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 11, 1, 11, 11 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 11, 1, 11, 11 ],
+ "errorMsg" : "Cannot apply operator `+` on types `` and ``",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ },
+ "left" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 11, 1, 11, 4 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ },
+ "operator" : "+",
+ "right" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 11, 8, 11, 11 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 12, 1, 12, 12 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 12, 1, 12, 12 ],
+ "errorMsg" : "Cannot apply operator `==` on types `` and ``",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "left" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 12, 1, 12, 4 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ },
+ "operator" : "==",
+ "right" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 12, 9, 12, 12 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 13, 1, 13, 12 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 13, 1, 13, 12 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "left" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 13, 1, 13, 4 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ },
+ "operator" : "is",
+ "right" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 13, 9, 13, 12 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ }
+ } ],
+ "errors" : {
+ "errors" : [ {
+ "kind" : "CompilerError",
+ "location" : [ 1, 1, 1, 7 ],
+ "message" : "Cannot apply operator `and` on types `int` and `int`"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 2, 1, 2, 6 ],
+ "message" : "Cannot apply operator `or` on types `int` and `int`"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 3, 1, 3, 12 ],
+ "message" : "Cannot apply operator `-` on types `bool` and `bool`"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 4, 1, 4, 12 ],
+ "message" : "Cannot apply operator `<` on types `bool` and `bool`"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 5, 1, 5, 8 ],
+ "message" : "Cannot apply operator `+` on types `int` and `bool`"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 6, 1, 6, 9 ],
+ "message" : "Cannot apply operator `+` on types `bool` and `int`"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 7, 1, 7, 9 ],
+ "message" : "Cannot apply operator `==` on types `int` and `bool`"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 8, 1, 8, 10 ],
+ "message" : "Cannot apply operator `!=` on types `bool` and `int`"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 9, 1, 9, 6 ],
+ "message" : "Cannot apply operator `is` on types `int` and `int`"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 10, 1, 10, 13 ],
+ "message" : "Cannot apply operator `is` on types `bool` and `bool`"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 11, 1, 11, 11 ],
+ "message" : "Cannot apply operator `+` on types `` and ``"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 12, 1, 12, 12 ],
+ "message" : "Cannot apply operator `==` on types `` and ``"
+ } ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_expr_if.py b/src/test/data/pa2/sample/bad_expr_if.py
new file mode 100644
index 0000000..4ae5fbe
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_expr_if.py
@@ -0,0 +1,2 @@
+x: int = 0
+x = "Hello" if 2 > 3 else 3
diff --git a/src/test/data/pa2/sample/bad_expr_if.py.ast b/src/test/data/pa2/sample/bad_expr_if.py.ast
new file mode 100644
index 0000000..24d9ed3
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_expr_if.py.ast
@@ -0,0 +1,70 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 2, 28 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 6 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 4, 1, 6 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 10, 1, 10 ],
+ "value" : 0
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 2, 1, 2, 27 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 2, 1, 2, 1 ],
+ "name" : "x"
+ } ],
+ "value" : {
+ "kind" : "IfExpr",
+ "location" : [ 2, 5, 2, 27 ],
+ "condition" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 2, 16, 2, 20 ],
+ "left" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 16, 2, 16 ],
+ "value" : 2
+ },
+ "operator" : ">",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 20, 2, 20 ],
+ "value" : 3
+ }
+ },
+ "thenExpr" : {
+ "kind" : "StringLiteral",
+ "location" : [ 2, 5, 2, 11 ],
+ "value" : "Hello"
+ },
+ "elseExpr" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 27, 2, 27 ],
+ "value" : 3
+ }
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_expr_if.py.ast.typed b/src/test/data/pa2/sample/bad_expr_if.py.ast.typed
new file mode 100644
index 0000000..0da86f1
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_expr_if.py.ast.typed
@@ -0,0 +1,107 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 2, 28 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 6 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 4, 1, 6 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 10, 1, 10 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 0
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 2, 1, 2, 27 ],
+ "errorMsg" : "Expected type `int`; got type `object`",
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 2, 1, 2, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "x"
+ } ],
+ "value" : {
+ "kind" : "IfExpr",
+ "location" : [ 2, 5, 2, 27 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ },
+ "condition" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 2, 16, 2, 20 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "left" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 16, 2, 16 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 2
+ },
+ "operator" : ">",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 20, 2, 20 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 3
+ }
+ },
+ "thenExpr" : {
+ "kind" : "StringLiteral",
+ "location" : [ 2, 5, 2, 11 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "value" : "Hello"
+ },
+ "elseExpr" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 27, 2, 27 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 3
+ }
+ }
+ } ],
+ "errors" : {
+ "errors" : [ {
+ "kind" : "CompilerError",
+ "location" : [ 2, 1, 2, 27 ],
+ "message" : "Expected type `int`; got type `object`"
+ } ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_expr_unary.py b/src/test/data/pa2/sample/bad_expr_unary.py
new file mode 100644
index 0000000..0b113ac
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_expr_unary.py
@@ -0,0 +1,4 @@
+not "Bad"
+-True
+-None
+not []
diff --git a/src/test/data/pa2/sample/bad_expr_unary.py.ast b/src/test/data/pa2/sample/bad_expr_unary.py.ast
new file mode 100644
index 0000000..7632c06
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_expr_unary.py.ast
@@ -0,0 +1,62 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 4, 7 ],
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 1, 1, 1, 9 ],
+ "expr" : {
+ "kind" : "UnaryExpr",
+ "location" : [ 1, 1, 1, 9 ],
+ "operator" : "not",
+ "operand" : {
+ "kind" : "StringLiteral",
+ "location" : [ 1, 5, 1, 9 ],
+ "value" : "Bad"
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 2, 1, 2, 5 ],
+ "expr" : {
+ "kind" : "UnaryExpr",
+ "location" : [ 2, 1, 2, 5 ],
+ "operator" : "-",
+ "operand" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 2, 2, 2, 5 ],
+ "value" : true
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 3, 1, 3, 5 ],
+ "expr" : {
+ "kind" : "UnaryExpr",
+ "location" : [ 3, 1, 3, 5 ],
+ "operator" : "-",
+ "operand" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 3, 2, 3, 5 ]
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 4, 1, 4, 6 ],
+ "expr" : {
+ "kind" : "UnaryExpr",
+ "location" : [ 4, 1, 4, 6 ],
+ "operator" : "not",
+ "operand" : {
+ "kind" : "ListExpr",
+ "location" : [ 4, 5, 4, 6 ],
+ "elements" : [ ]
+ }
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_expr_unary.py.ast.typed b/src/test/data/pa2/sample/bad_expr_unary.py.ast.typed
new file mode 100644
index 0000000..f366c93
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_expr_unary.py.ast.typed
@@ -0,0 +1,114 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 4, 7 ],
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 1, 1, 1, 9 ],
+ "expr" : {
+ "kind" : "UnaryExpr",
+ "location" : [ 1, 1, 1, 9 ],
+ "errorMsg" : "Cannot apply operator `not` on type `str`",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "operator" : "not",
+ "operand" : {
+ "kind" : "StringLiteral",
+ "location" : [ 1, 5, 1, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "value" : "Bad"
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 2, 1, 2, 5 ],
+ "expr" : {
+ "kind" : "UnaryExpr",
+ "location" : [ 2, 1, 2, 5 ],
+ "errorMsg" : "Cannot apply operator `-` on type `bool`",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "operator" : "-",
+ "operand" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 2, 2, 2, 5 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : true
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 3, 1, 3, 5 ],
+ "expr" : {
+ "kind" : "UnaryExpr",
+ "location" : [ 3, 1, 3, 5 ],
+ "errorMsg" : "Cannot apply operator `-` on type ``",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "operator" : "-",
+ "operand" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 3, 2, 3, 5 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 4, 1, 4, 6 ],
+ "expr" : {
+ "kind" : "UnaryExpr",
+ "location" : [ 4, 1, 4, 6 ],
+ "errorMsg" : "Cannot apply operator `not` on type ``",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "operator" : "not",
+ "operand" : {
+ "kind" : "ListExpr",
+ "location" : [ 4, 5, 4, 6 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ },
+ "elements" : [ ]
+ }
+ }
+ } ],
+ "errors" : {
+ "errors" : [ {
+ "kind" : "CompilerError",
+ "location" : [ 1, 1, 1, 9 ],
+ "message" : "Cannot apply operator `not` on type `str`"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 2, 1, 2, 5 ],
+ "message" : "Cannot apply operator `-` on type `bool`"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 3, 1, 3, 5 ],
+ "message" : "Cannot apply operator `-` on type ``"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 4, 1, 4, 6 ],
+ "message" : "Cannot apply operator `not` on type ``"
+ } ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_func_def_call.py b/src/test/data/pa2/sample/bad_func_def_call.py
new file mode 100644
index 0000000..a929805
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_func_def_call.py
@@ -0,0 +1,13 @@
+def foo(x:str, y:bool) -> int:
+ return bar()
+
+def bar() -> int:
+ return 1
+
+# All of the below are bad calls
+foo("Hello")
+foo("Hello", False, 3)
+foo("Hello", 3)
+foo(1, "Hello")
+baz()
+
diff --git a/src/test/data/pa2/sample/bad_func_def_call.py.ast b/src/test/data/pa2/sample/bad_func_def_call.py.ast
new file mode 100644
index 0000000..64c0e9d
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_func_def_call.py.ast
@@ -0,0 +1,187 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 12, 6 ],
+ "declarations" : [ {
+ "kind" : "FuncDef",
+ "location" : [ 1, 1, 2, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 5, 1, 7 ],
+ "name" : "foo"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 1, 9, 1, 13 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 9 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 11, 1, 13 ],
+ "className" : "str"
+ }
+ }, {
+ "kind" : "TypedVar",
+ "location" : [ 1, 16, 1, 21 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 16, 1, 16 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 18, 1, 21 ],
+ "className" : "bool"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 27, 1, 29 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 2, 5, 2, 16 ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 2, 12, 2, 16 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 12, 2, 14 ],
+ "name" : "bar"
+ },
+ "args" : [ ]
+ }
+ } ]
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 4, 1, 5, 13 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 5, 4, 7 ],
+ "name" : "bar"
+ },
+ "params" : [ ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 14, 4, 16 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 5, 5, 5, 12 ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 5, 12, 5, 12 ],
+ "value" : 1
+ }
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 8, 1, 8, 12 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 8, 1, 8, 12 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 1, 8, 3 ],
+ "name" : "foo"
+ },
+ "args" : [ {
+ "kind" : "StringLiteral",
+ "location" : [ 8, 5, 8, 11 ],
+ "value" : "Hello"
+ } ]
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 9, 1, 9, 22 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 9, 1, 9, 22 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 1, 9, 3 ],
+ "name" : "foo"
+ },
+ "args" : [ {
+ "kind" : "StringLiteral",
+ "location" : [ 9, 5, 9, 11 ],
+ "value" : "Hello"
+ }, {
+ "kind" : "BooleanLiteral",
+ "location" : [ 9, 14, 9, 18 ],
+ "value" : false
+ }, {
+ "kind" : "IntegerLiteral",
+ "location" : [ 9, 21, 9, 21 ],
+ "value" : 3
+ } ]
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 10, 1, 10, 15 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 10, 1, 10, 15 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 10, 1, 10, 3 ],
+ "name" : "foo"
+ },
+ "args" : [ {
+ "kind" : "StringLiteral",
+ "location" : [ 10, 5, 10, 11 ],
+ "value" : "Hello"
+ }, {
+ "kind" : "IntegerLiteral",
+ "location" : [ 10, 14, 10, 14 ],
+ "value" : 3
+ } ]
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 11, 1, 11, 15 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 11, 1, 11, 15 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 1, 11, 3 ],
+ "name" : "foo"
+ },
+ "args" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 11, 5, 11, 5 ],
+ "value" : 1
+ }, {
+ "kind" : "StringLiteral",
+ "location" : [ 11, 8, 11, 14 ],
+ "value" : "Hello"
+ } ]
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 12, 1, 12, 5 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 12, 1, 12, 5 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 12, 1, 12, 3 ],
+ "name" : "baz"
+ },
+ "args" : [ ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_func_def_call.py.ast.typed b/src/test/data/pa2/sample/bad_func_def_call.py.ast.typed
new file mode 100644
index 0000000..e9dc647
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_func_def_call.py.ast.typed
@@ -0,0 +1,336 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 12, 6 ],
+ "declarations" : [ {
+ "kind" : "FuncDef",
+ "location" : [ 1, 1, 2, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 5, 1, 7 ],
+ "name" : "foo"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 1, 9, 1, 13 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 9 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 11, 1, 13 ],
+ "className" : "str"
+ }
+ }, {
+ "kind" : "TypedVar",
+ "location" : [ 1, 16, 1, 21 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 16, 1, 16 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 18, 1, 21 ],
+ "className" : "bool"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 27, 1, 29 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 2, 5, 2, 16 ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 2, 12, 2, 16 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 12, 2, 14 ],
+ "inferredType" : {
+ "kind" : "FuncType",
+ "parameters" : [ ],
+ "returnType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "name" : "bar"
+ },
+ "args" : [ ]
+ }
+ } ]
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 4, 1, 5, 13 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 5, 4, 7 ],
+ "name" : "bar"
+ },
+ "params" : [ ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 14, 4, 16 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 5, 5, 5, 12 ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 5, 12, 5, 12 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 8, 1, 8, 12 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 8, 1, 8, 12 ],
+ "errorMsg" : "Expected 2 arguments; got 1",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 1, 8, 3 ],
+ "inferredType" : {
+ "kind" : "FuncType",
+ "parameters" : [ {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ }, {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ } ],
+ "returnType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "name" : "foo"
+ },
+ "args" : [ {
+ "kind" : "StringLiteral",
+ "location" : [ 8, 5, 8, 11 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "value" : "Hello"
+ } ]
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 9, 1, 9, 22 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 9, 1, 9, 22 ],
+ "errorMsg" : "Expected 2 arguments; got 3",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 1, 9, 3 ],
+ "inferredType" : {
+ "kind" : "FuncType",
+ "parameters" : [ {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ }, {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ } ],
+ "returnType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "name" : "foo"
+ },
+ "args" : [ {
+ "kind" : "StringLiteral",
+ "location" : [ 9, 5, 9, 11 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "value" : "Hello"
+ }, {
+ "kind" : "BooleanLiteral",
+ "location" : [ 9, 14, 9, 18 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : false
+ }, {
+ "kind" : "IntegerLiteral",
+ "location" : [ 9, 21, 9, 21 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 3
+ } ]
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 10, 1, 10, 15 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 10, 1, 10, 15 ],
+ "errorMsg" : "Expected type `bool`; got type `int` in parameter 1",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 10, 1, 10, 3 ],
+ "inferredType" : {
+ "kind" : "FuncType",
+ "parameters" : [ {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ }, {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ } ],
+ "returnType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "name" : "foo"
+ },
+ "args" : [ {
+ "kind" : "StringLiteral",
+ "location" : [ 10, 5, 10, 11 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "value" : "Hello"
+ }, {
+ "kind" : "IntegerLiteral",
+ "location" : [ 10, 14, 10, 14 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 3
+ } ]
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 11, 1, 11, 15 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 11, 1, 11, 15 ],
+ "errorMsg" : "Expected type `str`; got type `int` in parameter 0",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 1, 11, 3 ],
+ "inferredType" : {
+ "kind" : "FuncType",
+ "parameters" : [ {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ }, {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ } ],
+ "returnType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "name" : "foo"
+ },
+ "args" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 11, 5, 11, 5 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }, {
+ "kind" : "StringLiteral",
+ "location" : [ 11, 8, 11, 14 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "value" : "Hello"
+ } ]
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 12, 1, 12, 5 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 12, 1, 12, 5 ],
+ "errorMsg" : "Not a function or class: baz",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 12, 1, 12, 3 ],
+ "name" : "baz"
+ },
+ "args" : [ ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ {
+ "kind" : "CompilerError",
+ "location" : [ 8, 1, 8, 12 ],
+ "message" : "Expected 2 arguments; got 1"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 9, 1, 9, 22 ],
+ "message" : "Expected 2 arguments; got 3"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 10, 1, 10, 15 ],
+ "message" : "Expected type `bool`; got type `int` in parameter 1"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 11, 1, 11, 15 ],
+ "message" : "Expected type `str`; got type `int` in parameter 0"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 12, 1, 12, 5 ],
+ "message" : "Not a function or class: baz"
+ } ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_func_def_return.py b/src/test/data/pa2/sample/bad_func_def_return.py
new file mode 100644
index 0000000..efccffb
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_func_def_return.py
@@ -0,0 +1,10 @@
+def foo(x:str, y:bool) -> int:
+ return None
+
+def bar() -> bool:
+ return 1
+
+def baz() -> str:
+ return
+
+foo("Hello", False)
diff --git a/src/test/data/pa2/sample/bad_func_def_return.py.ast b/src/test/data/pa2/sample/bad_func_def_return.py.ast
new file mode 100644
index 0000000..e7aaa31
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_func_def_return.py.ast
@@ -0,0 +1,125 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 10, 20 ],
+ "declarations" : [ {
+ "kind" : "FuncDef",
+ "location" : [ 1, 1, 2, 16 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 5, 1, 7 ],
+ "name" : "foo"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 1, 9, 1, 13 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 9 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 11, 1, 13 ],
+ "className" : "str"
+ }
+ }, {
+ "kind" : "TypedVar",
+ "location" : [ 1, 16, 1, 21 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 16, 1, 16 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 18, 1, 21 ],
+ "className" : "bool"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 27, 1, 29 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 2, 5, 2, 15 ],
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 2, 12, 2, 15 ]
+ }
+ } ]
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 4, 1, 5, 13 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 5, 4, 7 ],
+ "name" : "bar"
+ },
+ "params" : [ ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 14, 4, 17 ],
+ "className" : "bool"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 5, 5, 5, 12 ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 5, 12, 5, 12 ],
+ "value" : 1
+ }
+ } ]
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 7, 1, 8, 11 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 5, 7, 7 ],
+ "name" : "baz"
+ },
+ "params" : [ ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 7, 14, 7, 16 ],
+ "className" : "str"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 8, 5, 8, 10 ],
+ "value" : null
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 10, 1, 10, 19 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 10, 1, 10, 19 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 10, 1, 10, 3 ],
+ "name" : "foo"
+ },
+ "args" : [ {
+ "kind" : "StringLiteral",
+ "location" : [ 10, 5, 10, 11 ],
+ "value" : "Hello"
+ }, {
+ "kind" : "BooleanLiteral",
+ "location" : [ 10, 14, 10, 18 ],
+ "value" : false
+ } ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_func_def_return.py.ast.typed b/src/test/data/pa2/sample/bad_func_def_return.py.ast.typed
new file mode 100644
index 0000000..8dafad8
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_func_def_return.py.ast.typed
@@ -0,0 +1,174 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 10, 20 ],
+ "declarations" : [ {
+ "kind" : "FuncDef",
+ "location" : [ 1, 1, 2, 16 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 5, 1, 7 ],
+ "name" : "foo"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 1, 9, 1, 13 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 9 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 11, 1, 13 ],
+ "className" : "str"
+ }
+ }, {
+ "kind" : "TypedVar",
+ "location" : [ 1, 16, 1, 21 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 16, 1, 16 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 18, 1, 21 ],
+ "className" : "bool"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 27, 1, 29 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 2, 5, 2, 15 ],
+ "errorMsg" : "Expected type `int`; got type ``",
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 2, 12, 2, 15 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ } ]
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 4, 1, 5, 13 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 5, 4, 7 ],
+ "name" : "bar"
+ },
+ "params" : [ ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 14, 4, 17 ],
+ "className" : "bool"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 5, 5, 5, 12 ],
+ "errorMsg" : "Expected type `bool`; got type `int`",
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 5, 12, 5, 12 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ } ]
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 7, 1, 8, 11 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 5, 7, 7 ],
+ "name" : "baz"
+ },
+ "params" : [ ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 7, 14, 7, 16 ],
+ "className" : "str"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 8, 5, 8, 10 ],
+ "errorMsg" : "Expected type `str`; got `None`",
+ "value" : null
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 10, 1, 10, 19 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 10, 1, 10, 19 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 10, 1, 10, 3 ],
+ "inferredType" : {
+ "kind" : "FuncType",
+ "parameters" : [ {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ }, {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ } ],
+ "returnType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "name" : "foo"
+ },
+ "args" : [ {
+ "kind" : "StringLiteral",
+ "location" : [ 10, 5, 10, 11 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "value" : "Hello"
+ }, {
+ "kind" : "BooleanLiteral",
+ "location" : [ 10, 14, 10, 18 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : false
+ } ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ {
+ "kind" : "CompilerError",
+ "location" : [ 2, 5, 2, 15 ],
+ "message" : "Expected type `int`; got type ``"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 5, 5, 5, 12 ],
+ "message" : "Expected type `bool`; got type `int`"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 8, 5, 8, 10 ],
+ "message" : "Expected type `str`; got `None`"
+ } ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_list_assign.py b/src/test/data/pa2/sample/bad_list_assign.py
new file mode 100644
index 0000000..f85c242
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_list_assign.py
@@ -0,0 +1,6 @@
+x:[int] = None
+y:[object] = None
+
+x = [1, 2, 3]
+y = x
+y = [1]
diff --git a/src/test/data/pa2/sample/bad_list_assign.py.ast b/src/test/data/pa2/sample/bad_list_assign.py.ast
new file mode 100644
index 0000000..5fa5dd5
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_list_assign.py.ast
@@ -0,0 +1,116 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 6, 8 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 14 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 7 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ListType",
+ "location" : [ 1, 3, 1, 7 ],
+ "elementType" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 4, 1, 6 ],
+ "className" : "int"
+ }
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 1, 11, 1, 14 ]
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 2, 1, 2, 17 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 1, 2, 10 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 1, 2, 1 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ListType",
+ "location" : [ 2, 3, 2, 10 ],
+ "elementType" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 4, 2, 9 ],
+ "className" : "object"
+ }
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 2, 14, 2, 17 ]
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 4, 1, 4, 13 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 4, 1, 4, 1 ],
+ "name" : "x"
+ } ],
+ "value" : {
+ "kind" : "ListExpr",
+ "location" : [ 4, 5, 4, 13 ],
+ "elements" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 4, 6, 4, 6 ],
+ "value" : 1
+ }, {
+ "kind" : "IntegerLiteral",
+ "location" : [ 4, 9, 4, 9 ],
+ "value" : 2
+ }, {
+ "kind" : "IntegerLiteral",
+ "location" : [ 4, 12, 4, 12 ],
+ "value" : 3
+ } ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 5, 1, 5, 5 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 5, 1, 5, 1 ],
+ "name" : "y"
+ } ],
+ "value" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 5, 5, 5 ],
+ "name" : "x"
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 6, 1, 6, 7 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 6, 1, 6, 1 ],
+ "name" : "y"
+ } ],
+ "value" : {
+ "kind" : "ListExpr",
+ "location" : [ 6, 5, 6, 7 ],
+ "elements" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 6, 6, 6 ],
+ "value" : 1
+ } ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_list_assign.py.ast.typed b/src/test/data/pa2/sample/bad_list_assign.py.ast.typed
new file mode 100644
index 0000000..b07e2b3
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_list_assign.py.ast.typed
@@ -0,0 +1,192 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 6, 8 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 14 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 7 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ListType",
+ "location" : [ 1, 3, 1, 7 ],
+ "elementType" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 4, 1, 6 ],
+ "className" : "int"
+ }
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 1, 11, 1, 14 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 2, 1, 2, 17 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 1, 2, 10 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 1, 2, 1 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ListType",
+ "location" : [ 2, 3, 2, 10 ],
+ "elementType" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 4, 2, 9 ],
+ "className" : "object"
+ }
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 2, 14, 2, 17 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 4, 1, 4, 13 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 4, 1, 4, 1 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "name" : "x"
+ } ],
+ "value" : {
+ "kind" : "ListExpr",
+ "location" : [ 4, 5, 4, 13 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "elements" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 4, 6, 4, 6 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }, {
+ "kind" : "IntegerLiteral",
+ "location" : [ 4, 9, 4, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 2
+ }, {
+ "kind" : "IntegerLiteral",
+ "location" : [ 4, 12, 4, 12 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 3
+ } ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 5, 1, 5, 5 ],
+ "errorMsg" : "Expected type `[object]`; got type `[int]`",
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 5, 1, 5, 1 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ }
+ },
+ "name" : "y"
+ } ],
+ "value" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 5, 5, 5 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "name" : "x"
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 6, 1, 6, 7 ],
+ "errorMsg" : "Expected type `[object]`; got type `[int]`",
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 6, 1, 6, 1 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ }
+ },
+ "name" : "y"
+ } ],
+ "value" : {
+ "kind" : "ListExpr",
+ "location" : [ 6, 5, 6, 7 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "elements" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 6, 6, 6 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ } ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ {
+ "kind" : "CompilerError",
+ "location" : [ 5, 1, 5, 5 ],
+ "message" : "Expected type `[object]`; got type `[int]`"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 6, 1, 6, 7 ],
+ "message" : "Expected type `[object]`; got type `[int]`"
+ } ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_list_index.py b/src/test/data/pa2/sample/bad_list_index.py
new file mode 100644
index 0000000..7b0c708
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_list_index.py
@@ -0,0 +1,7 @@
+x:[int] = None
+
+x = [1, 2, 3]
+x[True] # Bad
+False[0] # Bad
+[][0] # Bad
+x[True] = x[False] = 1
diff --git a/src/test/data/pa2/sample/bad_list_index.py.ast b/src/test/data/pa2/sample/bad_list_index.py.ast
new file mode 100644
index 0000000..b805e51
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_list_index.py.ast
@@ -0,0 +1,147 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 7, 23 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 14 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 7 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ListType",
+ "location" : [ 1, 3, 1, 7 ],
+ "elementType" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 4, 1, 6 ],
+ "className" : "int"
+ }
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 1, 11, 1, 14 ]
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 3, 1, 3, 13 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 3, 1, 3, 1 ],
+ "name" : "x"
+ } ],
+ "value" : {
+ "kind" : "ListExpr",
+ "location" : [ 3, 5, 3, 13 ],
+ "elements" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 3, 6, 3, 6 ],
+ "value" : 1
+ }, {
+ "kind" : "IntegerLiteral",
+ "location" : [ 3, 9, 3, 9 ],
+ "value" : 2
+ }, {
+ "kind" : "IntegerLiteral",
+ "location" : [ 3, 12, 3, 12 ],
+ "value" : 3
+ } ]
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 4, 1, 4, 7 ],
+ "expr" : {
+ "kind" : "IndexExpr",
+ "location" : [ 4, 1, 4, 7 ],
+ "list" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 1, 4, 1 ],
+ "name" : "x"
+ },
+ "index" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 4, 3, 4, 6 ],
+ "value" : true
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 5, 1, 5, 8 ],
+ "expr" : {
+ "kind" : "IndexExpr",
+ "location" : [ 5, 1, 5, 8 ],
+ "list" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 5, 1, 5, 5 ],
+ "value" : false
+ },
+ "index" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 5, 7, 5, 7 ],
+ "value" : 0
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 6, 1, 6, 5 ],
+ "expr" : {
+ "kind" : "IndexExpr",
+ "location" : [ 6, 1, 6, 5 ],
+ "list" : {
+ "kind" : "ListExpr",
+ "location" : [ 6, 1, 6, 2 ],
+ "elements" : [ ]
+ },
+ "index" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 4, 6, 4 ],
+ "value" : 0
+ }
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 7, 1, 7, 22 ],
+ "targets" : [ {
+ "kind" : "IndexExpr",
+ "location" : [ 7, 1, 7, 7 ],
+ "list" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 1, 7, 1 ],
+ "name" : "x"
+ },
+ "index" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 7, 3, 7, 6 ],
+ "value" : true
+ }
+ }, {
+ "kind" : "IndexExpr",
+ "location" : [ 7, 11, 7, 18 ],
+ "list" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 11, 7, 11 ],
+ "name" : "x"
+ },
+ "index" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 7, 13, 7, 17 ],
+ "value" : false
+ }
+ } ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 7, 22, 7, 22 ],
+ "value" : 1
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_list_index.py.ast.typed b/src/test/data/pa2/sample/bad_list_index.py.ast.typed
new file mode 100644
index 0000000..fa390f3
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_list_index.py.ast.typed
@@ -0,0 +1,275 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 7, 23 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 14 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 7 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ListType",
+ "location" : [ 1, 3, 1, 7 ],
+ "elementType" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 4, 1, 6 ],
+ "className" : "int"
+ }
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 1, 11, 1, 14 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 3, 1, 3, 13 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 3, 1, 3, 1 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "name" : "x"
+ } ],
+ "value" : {
+ "kind" : "ListExpr",
+ "location" : [ 3, 5, 3, 13 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "elements" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 3, 6, 3, 6 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }, {
+ "kind" : "IntegerLiteral",
+ "location" : [ 3, 9, 3, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 2
+ }, {
+ "kind" : "IntegerLiteral",
+ "location" : [ 3, 12, 3, 12 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 3
+ } ]
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 4, 1, 4, 7 ],
+ "expr" : {
+ "kind" : "IndexExpr",
+ "location" : [ 4, 1, 4, 7 ],
+ "errorMsg" : "Index is of non-integer type `bool`",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "list" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 1, 4, 1 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "name" : "x"
+ },
+ "index" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 4, 3, 4, 6 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : true
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 5, 1, 5, 8 ],
+ "expr" : {
+ "kind" : "IndexExpr",
+ "location" : [ 5, 1, 5, 8 ],
+ "errorMsg" : "Cannot index into type `bool`",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ },
+ "list" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 5, 1, 5, 5 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : false
+ },
+ "index" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 5, 7, 5, 7 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 0
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 6, 1, 6, 5 ],
+ "expr" : {
+ "kind" : "IndexExpr",
+ "location" : [ 6, 1, 6, 5 ],
+ "errorMsg" : "Cannot index into type ``",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ },
+ "list" : {
+ "kind" : "ListExpr",
+ "location" : [ 6, 1, 6, 2 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ },
+ "elements" : [ ]
+ },
+ "index" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 4, 6, 4 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 0
+ }
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 7, 1, 7, 22 ],
+ "targets" : [ {
+ "kind" : "IndexExpr",
+ "location" : [ 7, 1, 7, 7 ],
+ "errorMsg" : "Index is of non-integer type `bool`",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "list" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 1, 7, 1 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "name" : "x"
+ },
+ "index" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 7, 3, 7, 6 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : true
+ }
+ }, {
+ "kind" : "IndexExpr",
+ "location" : [ 7, 11, 7, 18 ],
+ "errorMsg" : "Index is of non-integer type `bool`",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "list" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 11, 7, 11 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "name" : "x"
+ },
+ "index" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 7, 13, 7, 17 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : false
+ }
+ } ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 7, 22, 7, 22 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ } ],
+ "errors" : {
+ "errors" : [ {
+ "kind" : "CompilerError",
+ "location" : [ 4, 1, 4, 7 ],
+ "message" : "Index is of non-integer type `bool`"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 5, 1, 5, 8 ],
+ "message" : "Cannot index into type `bool`"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 6, 1, 6, 5 ],
+ "message" : "Cannot index into type ``"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 7, 1, 7, 7 ],
+ "message" : "Index is of non-integer type `bool`"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 7, 11, 7, 18 ],
+ "message" : "Index is of non-integer type `bool`"
+ } ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_local_assign.py b/src/test/data/pa2/sample/bad_local_assign.py
new file mode 100644
index 0000000..77f3420
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_local_assign.py
@@ -0,0 +1,23 @@
+x:int = 1
+y:int = 2
+z:int = 3
+
+def foo(x:int) -> object:
+ y:int = 4 # OK
+ global z # OK
+
+ def qux() -> int:
+ y = 1 # Bad, nonlocal not declared
+ return 0
+
+ z = 1 # OK
+
+ pass
+
+def bar(x:int) -> int:
+ z = 1 # Bad, global not declared
+ return x
+
+
+foo(1)
+
diff --git a/src/test/data/pa2/sample/bad_local_assign.py.ast b/src/test/data/pa2/sample/bad_local_assign.py.ast
new file mode 100644
index 0000000..ffac6b5
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_local_assign.py.ast
@@ -0,0 +1,253 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 22, 7 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 3, 1, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 9, 1, 9 ],
+ "value" : 1
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 2, 1, 2, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 1, 2, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 1, 2, 1 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 3, 2, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 9, 2, 9 ],
+ "value" : 2
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 3, 1, 3, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 3, 1, 3, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 1, 3, 1 ],
+ "name" : "z"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 3, 3, 3, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 3, 9, 3, 9 ],
+ "value" : 3
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 5, 1, 15, 9 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 5, 5, 7 ],
+ "name" : "foo"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 5, 9, 5, 13 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 9, 5, 9 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 11, 5, 13 ],
+ "className" : "int"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 19, 5, 24 ],
+ "className" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 6, 5, 6, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 6, 5, 6, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 6, 5, 6, 5 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 6, 7, 6, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 13, 6, 13 ],
+ "value" : 4
+ }
+ }, {
+ "kind" : "GlobalDecl",
+ "location" : [ 7, 5, 7, 12 ],
+ "variable" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 12, 7, 12 ],
+ "name" : "z"
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 9, 5, 11, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 9, 9, 11 ],
+ "name" : "qux"
+ },
+ "params" : [ ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 9, 18, 9, 20 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 10, 9, 10, 13 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 10, 9, 10, 9 ],
+ "name" : "y"
+ } ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 10, 13, 10, 13 ],
+ "value" : 1
+ }
+ }, {
+ "kind" : "ReturnStmt",
+ "location" : [ 11, 9, 11, 16 ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 11, 16, 11, 16 ],
+ "value" : 0
+ }
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 13, 5, 13, 9 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 13, 5, 13, 5 ],
+ "name" : "z"
+ } ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 13, 9, 13, 9 ],
+ "value" : 1
+ }
+ } ]
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 17, 1, 19, 13 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 17, 5, 17, 7 ],
+ "name" : "bar"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 17, 9, 17, 13 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 17, 9, 17, 9 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 17, 11, 17, 13 ],
+ "className" : "int"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 17, 19, 17, 21 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 18, 5, 18, 9 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 18, 5, 18, 5 ],
+ "name" : "z"
+ } ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 18, 9, 18, 9 ],
+ "value" : 1
+ }
+ }, {
+ "kind" : "ReturnStmt",
+ "location" : [ 19, 5, 19, 12 ],
+ "value" : {
+ "kind" : "Identifier",
+ "location" : [ 19, 12, 19, 12 ],
+ "name" : "x"
+ }
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 22, 1, 22, 6 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 22, 1, 22, 6 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 22, 1, 22, 3 ],
+ "name" : "foo"
+ },
+ "args" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 22, 5, 22, 5 ],
+ "value" : 1
+ } ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_local_assign.py.ast.typed b/src/test/data/pa2/sample/bad_local_assign.py.ast.typed
new file mode 100644
index 0000000..ec39de4
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_local_assign.py.ast.typed
@@ -0,0 +1,330 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 22, 7 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 3, 1, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 9, 1, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 2, 1, 2, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 1, 2, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 1, 2, 1 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 3, 2, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 9, 2, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 2
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 3, 1, 3, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 3, 1, 3, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 1, 3, 1 ],
+ "name" : "z"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 3, 3, 3, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 3, 9, 3, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 3
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 5, 1, 15, 9 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 5, 5, 7 ],
+ "name" : "foo"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 5, 9, 5, 13 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 9, 5, 9 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 11, 5, 13 ],
+ "className" : "int"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 19, 5, 24 ],
+ "className" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 6, 5, 6, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 6, 5, 6, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 6, 5, 6, 5 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 6, 7, 6, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 13, 6, 13 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 4
+ }
+ }, {
+ "kind" : "GlobalDecl",
+ "location" : [ 7, 5, 7, 12 ],
+ "variable" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 12, 7, 12 ],
+ "name" : "z"
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 9, 5, 11, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 9, 9, 11 ],
+ "name" : "qux"
+ },
+ "params" : [ ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 9, 18, 9, 20 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 10, 9, 10, 13 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 10, 9, 10, 9 ],
+ "errorMsg" : "Cannot assign to variable that is not explicitly declared in this scope: y",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "y"
+ } ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 10, 13, 10, 13 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ }, {
+ "kind" : "ReturnStmt",
+ "location" : [ 11, 9, 11, 16 ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 11, 16, 11, 16 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 0
+ }
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 13, 5, 13, 9 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 13, 5, 13, 5 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "z"
+ } ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 13, 9, 13, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ } ]
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 17, 1, 19, 13 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 17, 5, 17, 7 ],
+ "name" : "bar"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 17, 9, 17, 13 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 17, 9, 17, 9 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 17, 11, 17, 13 ],
+ "className" : "int"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 17, 19, 17, 21 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 18, 5, 18, 9 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 18, 5, 18, 5 ],
+ "errorMsg" : "Cannot assign to variable that is not explicitly declared in this scope: z",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "z"
+ } ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 18, 9, 18, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ }, {
+ "kind" : "ReturnStmt",
+ "location" : [ 19, 5, 19, 12 ],
+ "value" : {
+ "kind" : "Identifier",
+ "location" : [ 19, 12, 19, 12 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "x"
+ }
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 22, 1, 22, 6 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 22, 1, 22, 6 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 22, 1, 22, 3 ],
+ "inferredType" : {
+ "kind" : "FuncType",
+ "parameters" : [ {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ } ],
+ "returnType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ }
+ },
+ "name" : "foo"
+ },
+ "args" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 22, 5, 22, 5 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ } ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ {
+ "kind" : "CompilerError",
+ "location" : [ 10, 9, 10, 9 ],
+ "message" : "Cannot assign to variable that is not explicitly declared in this scope: y"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 18, 5, 18, 5 ],
+ "message" : "Cannot assign to variable that is not explicitly declared in this scope: z"
+ } ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_none_assign.py b/src/test/data/pa2/sample/bad_none_assign.py
new file mode 100644
index 0000000..fc0ec3f
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_none_assign.py
@@ -0,0 +1,14 @@
+class A(object):
+ x:int = 1
+
+y:[bool] = None
+z:str = ""
+a:A = None
+
+a = A()
+
+# Cannot assign None to integer/bool/str types
+z = None
+a.x = None
+y[0] = None
+
diff --git a/src/test/data/pa2/sample/bad_none_assign.py.ast b/src/test/data/pa2/sample/bad_none_assign.py.ast
new file mode 100644
index 0000000..a0a1246
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_none_assign.py.ast
@@ -0,0 +1,187 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 13, 12 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 1, 1, 2, 14 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 7, 1, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 2, 5, 2, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 5, 2, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 5, 2, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 7, 2, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 13, 2, 13 ],
+ "value" : 1
+ }
+ } ]
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 4, 1, 4, 15 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 4, 1, 4, 8 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 1, 4, 1 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ListType",
+ "location" : [ 4, 3, 4, 8 ],
+ "elementType" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 4, 4, 7 ],
+ "className" : "bool"
+ }
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 4, 12, 4, 15 ]
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 5, 1, 5, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 5, 1, 5, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 1, 5, 1 ],
+ "name" : "z"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 3, 5, 5 ],
+ "className" : "str"
+ }
+ },
+ "value" : {
+ "kind" : "StringLiteral",
+ "location" : [ 5, 9, 5, 10 ],
+ "value" : ""
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 6, 1, 6, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 6, 1, 6, 3 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 6, 1, 6, 1 ],
+ "name" : "a"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 6, 3, 6, 3 ],
+ "className" : "A"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 6, 7, 6, 10 ]
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 8, 1, 8, 7 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 8, 1, 8, 1 ],
+ "name" : "a"
+ } ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 8, 5, 8, 7 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 5, 8, 5 ],
+ "name" : "A"
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 11, 1, 11, 8 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 11, 1, 11, 1 ],
+ "name" : "z"
+ } ],
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 11, 5, 11, 8 ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 12, 1, 12, 10 ],
+ "targets" : [ {
+ "kind" : "MemberExpr",
+ "location" : [ 12, 1, 12, 3 ],
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 12, 1, 12, 1 ],
+ "name" : "a"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 12, 3, 12, 3 ],
+ "name" : "x"
+ }
+ } ],
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 12, 7, 12, 10 ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 13, 1, 13, 11 ],
+ "targets" : [ {
+ "kind" : "IndexExpr",
+ "location" : [ 13, 1, 13, 4 ],
+ "list" : {
+ "kind" : "Identifier",
+ "location" : [ 13, 1, 13, 1 ],
+ "name" : "y"
+ },
+ "index" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 13, 3, 13, 3 ],
+ "value" : 0
+ }
+ } ],
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 13, 8, 13, 11 ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_none_assign.py.ast.typed b/src/test/data/pa2/sample/bad_none_assign.py.ast.typed
new file mode 100644
index 0000000..2edc3c2
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_none_assign.py.ast.typed
@@ -0,0 +1,265 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 13, 12 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 1, 1, 2, 14 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 7, 1, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 2, 5, 2, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 5, 2, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 5, 2, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 7, 2, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 13, 2, 13 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ } ]
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 4, 1, 4, 15 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 4, 1, 4, 8 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 1, 4, 1 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ListType",
+ "location" : [ 4, 3, 4, 8 ],
+ "elementType" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 4, 4, 7 ],
+ "className" : "bool"
+ }
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 4, 12, 4, 15 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 5, 1, 5, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 5, 1, 5, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 1, 5, 1 ],
+ "name" : "z"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 3, 5, 5 ],
+ "className" : "str"
+ }
+ },
+ "value" : {
+ "kind" : "StringLiteral",
+ "location" : [ 5, 9, 5, 10 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "value" : ""
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 6, 1, 6, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 6, 1, 6, 3 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 6, 1, 6, 1 ],
+ "name" : "a"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 6, 3, 6, 3 ],
+ "className" : "A"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 6, 7, 6, 10 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 8, 1, 8, 7 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 8, 1, 8, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "A"
+ },
+ "name" : "a"
+ } ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 8, 5, 8, 7 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "A"
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 5, 8, 5 ],
+ "name" : "A"
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 11, 1, 11, 8 ],
+ "errorMsg" : "Expected type `str`; got type ``",
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 11, 1, 11, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "name" : "z"
+ } ],
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 11, 5, 11, 8 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 12, 1, 12, 10 ],
+ "errorMsg" : "Expected type `int`; got type ``",
+ "targets" : [ {
+ "kind" : "MemberExpr",
+ "location" : [ 12, 1, 12, 3 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 12, 1, 12, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "A"
+ },
+ "name" : "a"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 12, 3, 12, 3 ],
+ "name" : "x"
+ }
+ } ],
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 12, 7, 12, 10 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 13, 1, 13, 11 ],
+ "errorMsg" : "Expected type `bool`; got type ``",
+ "targets" : [ {
+ "kind" : "IndexExpr",
+ "location" : [ 13, 1, 13, 4 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "list" : {
+ "kind" : "Identifier",
+ "location" : [ 13, 1, 13, 1 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ }
+ },
+ "name" : "y"
+ },
+ "index" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 13, 3, 13, 3 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 0
+ }
+ } ],
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 13, 8, 13, 11 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ } ],
+ "errors" : {
+ "errors" : [ {
+ "kind" : "CompilerError",
+ "location" : [ 11, 1, 11, 8 ],
+ "message" : "Expected type `str`; got type ``"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 12, 1, 12, 10 ],
+ "message" : "Expected type `int`; got type ``"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 13, 1, 13, 11 ],
+ "message" : "Expected type `bool`; got type ``"
+ } ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_nonlocal_global.py b/src/test/data/pa2/sample/bad_nonlocal_global.py
new file mode 100644
index 0000000..98eea5c
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_nonlocal_global.py
@@ -0,0 +1,25 @@
+x:int = 1
+y:int = 2
+z:int = 3
+
+def foo() -> object:
+ global x # OK
+ nonlocal y # No such nonlocal var
+ global w # No such global var
+ global int # No such global var
+
+ z:bool = True # OK
+
+ def bar() -> object:
+ global x # OK
+ nonlocal z # OK
+ nonlocal y # No such nonlocal var
+ global foo # No such global var
+ nonlocal bar # No such nonlocal var
+
+ pass
+
+ bar()
+
+foo()
+
diff --git a/src/test/data/pa2/sample/bad_nonlocal_global.py.ast b/src/test/data/pa2/sample/bad_nonlocal_global.py.ast
new file mode 100644
index 0000000..dce287d
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_nonlocal_global.py.ast
@@ -0,0 +1,229 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 24, 6 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 3, 1, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 9, 1, 9 ],
+ "value" : 1
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 2, 1, 2, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 1, 2, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 1, 2, 1 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 3, 2, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 9, 2, 9 ],
+ "value" : 2
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 3, 1, 3, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 3, 1, 3, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 1, 3, 1 ],
+ "name" : "z"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 3, 3, 3, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 3, 9, 3, 9 ],
+ "value" : 3
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 5, 1, 22, 10 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 5, 5, 7 ],
+ "name" : "foo"
+ },
+ "params" : [ ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 14, 5, 19 ],
+ "className" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "GlobalDecl",
+ "location" : [ 6, 5, 6, 12 ],
+ "variable" : {
+ "kind" : "Identifier",
+ "location" : [ 6, 12, 6, 12 ],
+ "name" : "x"
+ }
+ }, {
+ "kind" : "NonLocalDecl",
+ "location" : [ 7, 5, 7, 14 ],
+ "variable" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 14, 7, 14 ],
+ "name" : "y"
+ }
+ }, {
+ "kind" : "GlobalDecl",
+ "location" : [ 8, 5, 8, 12 ],
+ "variable" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 12, 8, 12 ],
+ "name" : "w"
+ }
+ }, {
+ "kind" : "GlobalDecl",
+ "location" : [ 9, 5, 9, 14 ],
+ "variable" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 12, 9, 14 ],
+ "name" : "int"
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 11, 5, 11, 17 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 11, 5, 11, 10 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 5, 11, 5 ],
+ "name" : "z"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 11, 7, 11, 10 ],
+ "className" : "bool"
+ }
+ },
+ "value" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 11, 14, 11, 17 ],
+ "value" : true
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 13, 5, 20, 13 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 13, 9, 13, 11 ],
+ "name" : "bar"
+ },
+ "params" : [ ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 13, 18, 13, 23 ],
+ "className" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "GlobalDecl",
+ "location" : [ 14, 9, 14, 16 ],
+ "variable" : {
+ "kind" : "Identifier",
+ "location" : [ 14, 16, 14, 16 ],
+ "name" : "x"
+ }
+ }, {
+ "kind" : "NonLocalDecl",
+ "location" : [ 15, 9, 15, 18 ],
+ "variable" : {
+ "kind" : "Identifier",
+ "location" : [ 15, 18, 15, 18 ],
+ "name" : "z"
+ }
+ }, {
+ "kind" : "NonLocalDecl",
+ "location" : [ 16, 9, 16, 18 ],
+ "variable" : {
+ "kind" : "Identifier",
+ "location" : [ 16, 18, 16, 18 ],
+ "name" : "y"
+ }
+ }, {
+ "kind" : "GlobalDecl",
+ "location" : [ 17, 9, 17, 18 ],
+ "variable" : {
+ "kind" : "Identifier",
+ "location" : [ 17, 16, 17, 18 ],
+ "name" : "foo"
+ }
+ }, {
+ "kind" : "NonLocalDecl",
+ "location" : [ 18, 9, 18, 20 ],
+ "variable" : {
+ "kind" : "Identifier",
+ "location" : [ 18, 18, 18, 20 ],
+ "name" : "bar"
+ }
+ } ],
+ "statements" : [ ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 22, 5, 22, 9 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 22, 5, 22, 9 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 22, 5, 22, 7 ],
+ "name" : "bar"
+ },
+ "args" : [ ]
+ }
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 24, 1, 24, 5 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 24, 1, 24, 5 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 24, 1, 24, 3 ],
+ "name" : "foo"
+ },
+ "args" : [ ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_nonlocal_global.py.ast.typed b/src/test/data/pa2/sample/bad_nonlocal_global.py.ast.typed
new file mode 100644
index 0000000..3b80c08
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_nonlocal_global.py.ast.typed
@@ -0,0 +1,259 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 24, 6 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 3, 1, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 9, 1, 9 ],
+ "value" : 1
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 2, 1, 2, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 1, 2, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 1, 2, 1 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 3, 2, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 9, 2, 9 ],
+ "value" : 2
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 3, 1, 3, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 3, 1, 3, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 1, 3, 1 ],
+ "name" : "z"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 3, 3, 3, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 3, 9, 3, 9 ],
+ "value" : 3
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 5, 1, 22, 10 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 5, 5, 7 ],
+ "name" : "foo"
+ },
+ "params" : [ ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 14, 5, 19 ],
+ "className" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "GlobalDecl",
+ "location" : [ 6, 5, 6, 12 ],
+ "variable" : {
+ "kind" : "Identifier",
+ "location" : [ 6, 12, 6, 12 ],
+ "name" : "x"
+ }
+ }, {
+ "kind" : "NonLocalDecl",
+ "location" : [ 7, 5, 7, 14 ],
+ "variable" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 14, 7, 14 ],
+ "errorMsg" : "Not a nonlocal variable: y",
+ "name" : "y"
+ }
+ }, {
+ "kind" : "GlobalDecl",
+ "location" : [ 8, 5, 8, 12 ],
+ "variable" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 12, 8, 12 ],
+ "errorMsg" : "Not a global variable: w",
+ "name" : "w"
+ }
+ }, {
+ "kind" : "GlobalDecl",
+ "location" : [ 9, 5, 9, 14 ],
+ "variable" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 12, 9, 14 ],
+ "errorMsg" : "Not a global variable: int",
+ "name" : "int"
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 11, 5, 11, 17 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 11, 5, 11, 10 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 5, 11, 5 ],
+ "name" : "z"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 11, 7, 11, 10 ],
+ "className" : "bool"
+ }
+ },
+ "value" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 11, 14, 11, 17 ],
+ "value" : true
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 13, 5, 20, 13 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 13, 9, 13, 11 ],
+ "name" : "bar"
+ },
+ "params" : [ ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 13, 18, 13, 23 ],
+ "className" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "GlobalDecl",
+ "location" : [ 14, 9, 14, 16 ],
+ "variable" : {
+ "kind" : "Identifier",
+ "location" : [ 14, 16, 14, 16 ],
+ "name" : "x"
+ }
+ }, {
+ "kind" : "NonLocalDecl",
+ "location" : [ 15, 9, 15, 18 ],
+ "variable" : {
+ "kind" : "Identifier",
+ "location" : [ 15, 18, 15, 18 ],
+ "name" : "z"
+ }
+ }, {
+ "kind" : "NonLocalDecl",
+ "location" : [ 16, 9, 16, 18 ],
+ "variable" : {
+ "kind" : "Identifier",
+ "location" : [ 16, 18, 16, 18 ],
+ "errorMsg" : "Not a nonlocal variable: y",
+ "name" : "y"
+ }
+ }, {
+ "kind" : "GlobalDecl",
+ "location" : [ 17, 9, 17, 18 ],
+ "variable" : {
+ "kind" : "Identifier",
+ "location" : [ 17, 16, 17, 18 ],
+ "errorMsg" : "Not a global variable: foo",
+ "name" : "foo"
+ }
+ }, {
+ "kind" : "NonLocalDecl",
+ "location" : [ 18, 9, 18, 20 ],
+ "variable" : {
+ "kind" : "Identifier",
+ "location" : [ 18, 18, 18, 20 ],
+ "errorMsg" : "Not a nonlocal variable: bar",
+ "name" : "bar"
+ }
+ } ],
+ "statements" : [ ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 22, 5, 22, 9 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 22, 5, 22, 9 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 22, 5, 22, 7 ],
+ "name" : "bar"
+ },
+ "args" : [ ]
+ }
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 24, 1, 24, 5 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 24, 1, 24, 5 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 24, 1, 24, 3 ],
+ "name" : "foo"
+ },
+ "args" : [ ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ {
+ "kind" : "CompilerError",
+ "location" : [ 7, 14, 7, 14 ],
+ "message" : "Not a nonlocal variable: y"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 8, 12, 8, 12 ],
+ "message" : "Not a global variable: w"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 9, 12, 9, 14 ],
+ "message" : "Not a global variable: int"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 16, 18, 16, 18 ],
+ "message" : "Not a nonlocal variable: y"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 17, 16, 17, 18 ],
+ "message" : "Not a global variable: foo"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 18, 18, 18, 20 ],
+ "message" : "Not a nonlocal variable: bar"
+ } ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_return_missing.py b/src/test/data/pa2/sample/bad_return_missing.py
new file mode 100644
index 0000000..9200f93
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_return_missing.py
@@ -0,0 +1,6 @@
+def foo() -> int:
+ if True:
+ return 1
+ # Bad: all paths MUST return int
+
+foo()
diff --git a/src/test/data/pa2/sample/bad_return_missing.py.ast b/src/test/data/pa2/sample/bad_return_missing.py.ast
new file mode 100644
index 0000000..8efc035
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_return_missing.py.ast
@@ -0,0 +1,58 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 6, 6 ],
+ "declarations" : [ {
+ "kind" : "FuncDef",
+ "location" : [ 1, 1, 6, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 5, 1, 7 ],
+ "name" : "foo"
+ },
+ "params" : [ ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 14, 1, 16 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "IfStmt",
+ "location" : [ 2, 5, 6, 0 ],
+ "condition" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 2, 8, 2, 11 ],
+ "value" : true
+ },
+ "thenBody" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 3, 9, 3, 16 ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 3, 16, 3, 16 ],
+ "value" : 1
+ }
+ } ],
+ "elseBody" : [ ]
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 6, 1, 6, 5 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 6, 1, 6, 5 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 6, 1, 6, 3 ],
+ "name" : "foo"
+ },
+ "args" : [ ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_return_missing.py.ast.typed b/src/test/data/pa2/sample/bad_return_missing.py.ast.typed
new file mode 100644
index 0000000..627d4f3
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_return_missing.py.ast.typed
@@ -0,0 +1,63 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 6, 6 ],
+ "declarations" : [ {
+ "kind" : "FuncDef",
+ "location" : [ 1, 1, 6, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 5, 1, 7 ],
+ "errorMsg" : "All paths in this function/method must have a return statement: foo",
+ "name" : "foo"
+ },
+ "params" : [ ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 14, 1, 16 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "IfStmt",
+ "location" : [ 2, 5, 6, 0 ],
+ "condition" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 2, 8, 2, 11 ],
+ "value" : true
+ },
+ "thenBody" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 3, 9, 3, 16 ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 3, 16, 3, 16 ],
+ "value" : 1
+ }
+ } ],
+ "elseBody" : [ ]
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 6, 1, 6, 5 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 6, 1, 6, 5 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 6, 1, 6, 3 ],
+ "name" : "foo"
+ },
+ "args" : [ ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ {
+ "kind" : "CompilerError",
+ "location" : [ 1, 5, 1, 7 ],
+ "message" : "All paths in this function/method must have a return statement: foo"
+ } ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_return_top.py b/src/test/data/pa2/sample/bad_return_top.py
new file mode 100644
index 0000000..ca0d0e0
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_return_top.py
@@ -0,0 +1,3 @@
+x:int = 0
+
+return x
diff --git a/src/test/data/pa2/sample/bad_return_top.py.ast b/src/test/data/pa2/sample/bad_return_top.py.ast
new file mode 100644
index 0000000..992907a
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_return_top.py.ast
@@ -0,0 +1,41 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 3, 9 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 3, 1, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 9, 1, 9 ],
+ "value" : 0
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 3, 1, 3, 8 ],
+ "value" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 8, 3, 8 ],
+ "name" : "x"
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_return_top.py.ast.typed b/src/test/data/pa2/sample/bad_return_top.py.ast.typed
new file mode 100644
index 0000000..56df1de
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_return_top.py.ast.typed
@@ -0,0 +1,50 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 3, 9 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 3, 1, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 9, 1, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 0
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 3, 1, 3, 8 ],
+ "errorMsg" : "Return statement cannot appear at the top level",
+ "value" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 8, 3, 8 ],
+ "name" : "x"
+ }
+ } ],
+ "errors" : {
+ "errors" : [ {
+ "kind" : "CompilerError",
+ "location" : [ 3, 1, 3, 8 ],
+ "message" : "Return statement cannot appear at the top level"
+ } ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_shadow_local.py b/src/test/data/pa2/sample/bad_shadow_local.py
new file mode 100644
index 0000000..9fc916b
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_shadow_local.py
@@ -0,0 +1,14 @@
+class A(object):
+ x:int = 1
+
+def foo(x:int, bool:str) -> object: # Second param uses an invalid name
+ y:int = 4 # OK
+ A:int = 5 # Invalid name
+ object:str = "" # Invalid name
+
+ def str() -> bool: # Invalid name
+ return False
+
+ pass
+
+pass
diff --git a/src/test/data/pa2/sample/bad_shadow_local.py.ast b/src/test/data/pa2/sample/bad_shadow_local.py.ast
new file mode 100644
index 0000000..cff93dc
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_shadow_local.py.ast
@@ -0,0 +1,179 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 14, 5 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 1, 1, 2, 14 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 7, 1, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 2, 5, 2, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 5, 2, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 5, 2, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 7, 2, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 13, 2, 13 ],
+ "value" : 1
+ }
+ } ]
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 4, 1, 12, 9 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 5, 4, 7 ],
+ "name" : "foo"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 4, 9, 4, 13 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 9, 4, 9 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 11, 4, 13 ],
+ "className" : "int"
+ }
+ }, {
+ "kind" : "TypedVar",
+ "location" : [ 4, 16, 4, 23 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 16, 4, 19 ],
+ "name" : "bool"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 21, 4, 23 ],
+ "className" : "str"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 29, 4, 34 ],
+ "className" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 5, 5, 5, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 5, 5, 5, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 5, 5, 5 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 7, 5, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 5, 13, 5, 13 ],
+ "value" : 4
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 6, 5, 6, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 6, 5, 6, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 6, 5, 6, 5 ],
+ "name" : "A"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 6, 7, 6, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 13, 6, 13 ],
+ "value" : 5
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 7, 5, 7, 19 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 7, 5, 7, 14 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 5, 7, 10 ],
+ "name" : "object"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 7, 12, 7, 14 ],
+ "className" : "str"
+ }
+ },
+ "value" : {
+ "kind" : "StringLiteral",
+ "location" : [ 7, 18, 7, 19 ],
+ "value" : ""
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 9, 5, 10, 21 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 9, 9, 11 ],
+ "name" : "str"
+ },
+ "params" : [ ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 9, 18, 9, 21 ],
+ "className" : "bool"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 10, 9, 10, 20 ],
+ "value" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 10, 16, 10, 20 ],
+ "value" : false
+ }
+ } ]
+ } ],
+ "statements" : [ ]
+ } ],
+ "statements" : [ ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_shadow_local.py.ast.typed b/src/test/data/pa2/sample/bad_shadow_local.py.ast.typed
new file mode 100644
index 0000000..3cc9b9b
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_shadow_local.py.ast.typed
@@ -0,0 +1,199 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 14, 5 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 1, 1, 2, 14 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 7, 1, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 2, 5, 2, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 5, 2, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 5, 2, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 7, 2, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 13, 2, 13 ],
+ "value" : 1
+ }
+ } ]
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 4, 1, 12, 9 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 5, 4, 7 ],
+ "name" : "foo"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 4, 9, 4, 13 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 9, 4, 9 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 11, 4, 13 ],
+ "className" : "int"
+ }
+ }, {
+ "kind" : "TypedVar",
+ "location" : [ 4, 16, 4, 23 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 16, 4, 19 ],
+ "errorMsg" : "Cannot shadow class name: bool",
+ "name" : "bool"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 21, 4, 23 ],
+ "className" : "str"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 29, 4, 34 ],
+ "className" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 5, 5, 5, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 5, 5, 5, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 5, 5, 5 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 7, 5, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 5, 13, 5, 13 ],
+ "value" : 4
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 6, 5, 6, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 6, 5, 6, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 6, 5, 6, 5 ],
+ "errorMsg" : "Cannot shadow class name: A",
+ "name" : "A"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 6, 7, 6, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 13, 6, 13 ],
+ "value" : 5
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 7, 5, 7, 19 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 7, 5, 7, 14 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 5, 7, 10 ],
+ "errorMsg" : "Cannot shadow class name: object",
+ "name" : "object"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 7, 12, 7, 14 ],
+ "className" : "str"
+ }
+ },
+ "value" : {
+ "kind" : "StringLiteral",
+ "location" : [ 7, 18, 7, 19 ],
+ "value" : ""
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 9, 5, 10, 21 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 9, 9, 11 ],
+ "errorMsg" : "Cannot shadow class name: str",
+ "name" : "str"
+ },
+ "params" : [ ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 9, 18, 9, 21 ],
+ "className" : "bool"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 10, 9, 10, 20 ],
+ "value" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 10, 16, 10, 20 ],
+ "value" : false
+ }
+ } ]
+ } ],
+ "statements" : [ ]
+ } ],
+ "statements" : [ ],
+ "errors" : {
+ "errors" : [ {
+ "kind" : "CompilerError",
+ "location" : [ 4, 16, 4, 19 ],
+ "message" : "Cannot shadow class name: bool"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 6, 5, 6, 5 ],
+ "message" : "Cannot shadow class name: A"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 7, 5, 7, 10 ],
+ "message" : "Cannot shadow class name: object"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 9, 9, 9, 11 ],
+ "message" : "Cannot shadow class name: str"
+ } ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_shadow_local_2.py b/src/test/data/pa2/sample/bad_shadow_local_2.py
new file mode 100644
index 0000000..67a327e
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_shadow_local_2.py
@@ -0,0 +1,8 @@
+def foo(x:int) -> object:
+ A:int = 5 # Invalid name
+ pass
+
+class A(object):
+ x:int = 1
+
+pass
diff --git a/src/test/data/pa2/sample/bad_shadow_local_2.py.ast b/src/test/data/pa2/sample/bad_shadow_local_2.py.ast
new file mode 100644
index 0000000..5eb5b2e
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_shadow_local_2.py.ast
@@ -0,0 +1,98 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 8, 5 ],
+ "declarations" : [ {
+ "kind" : "FuncDef",
+ "location" : [ 1, 1, 3, 9 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 5, 1, 7 ],
+ "name" : "foo"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 1, 9, 1, 13 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 9 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 11, 1, 13 ],
+ "className" : "int"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 19, 1, 24 ],
+ "className" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 2, 5, 2, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 5, 2, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 5, 2, 5 ],
+ "name" : "A"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 7, 2, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 13, 2, 13 ],
+ "value" : 5
+ }
+ } ],
+ "statements" : [ ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 5, 1, 6, 14 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 7, 5, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 9, 5, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 6, 5, 6, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 6, 5, 6, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 6, 5, 6, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 6, 7, 6, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 13, 6, 13 ],
+ "value" : 1
+ }
+ } ]
+ } ],
+ "statements" : [ ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_shadow_local_2.py.ast.typed b/src/test/data/pa2/sample/bad_shadow_local_2.py.ast.typed
new file mode 100644
index 0000000..ff6ef1b
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_shadow_local_2.py.ast.typed
@@ -0,0 +1,103 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 8, 5 ],
+ "declarations" : [ {
+ "kind" : "FuncDef",
+ "location" : [ 1, 1, 3, 9 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 5, 1, 7 ],
+ "name" : "foo"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 1, 9, 1, 13 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 9 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 11, 1, 13 ],
+ "className" : "int"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 19, 1, 24 ],
+ "className" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 2, 5, 2, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 5, 2, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 5, 2, 5 ],
+ "errorMsg" : "Cannot shadow class name: A",
+ "name" : "A"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 7, 2, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 13, 2, 13 ],
+ "value" : 5
+ }
+ } ],
+ "statements" : [ ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 5, 1, 6, 14 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 7, 5, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 9, 5, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 6, 5, 6, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 6, 5, 6, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 6, 5, 6, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 6, 7, 6, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 13, 6, 13 ],
+ "value" : 1
+ }
+ } ]
+ } ],
+ "statements" : [ ],
+ "errors" : {
+ "errors" : [ {
+ "kind" : "CompilerError",
+ "location" : [ 2, 5, 2, 5 ],
+ "message" : "Cannot shadow class name: A"
+ } ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_strings.py b/src/test/data/pa2/sample/bad_strings.py
new file mode 100644
index 0000000..86e0e16
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_strings.py
@@ -0,0 +1,10 @@
+x:str = "Hello"
+y:str = "World"
+z:str = ""
+
+1 + x
+z = x + 1
+z = x[0] = y
+x[1] = y
+x[True]
+
diff --git a/src/test/data/pa2/sample/bad_strings.py.ast b/src/test/data/pa2/sample/bad_strings.py.ast
new file mode 100644
index 0000000..04473bf
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_strings.py.ast
@@ -0,0 +1,183 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 9, 8 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 15 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 3, 1, 5 ],
+ "className" : "str"
+ }
+ },
+ "value" : {
+ "kind" : "StringLiteral",
+ "location" : [ 1, 9, 1, 15 ],
+ "value" : "Hello"
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 2, 1, 2, 15 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 1, 2, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 1, 2, 1 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 3, 2, 5 ],
+ "className" : "str"
+ }
+ },
+ "value" : {
+ "kind" : "StringLiteral",
+ "location" : [ 2, 9, 2, 15 ],
+ "value" : "World"
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 3, 1, 3, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 3, 1, 3, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 1, 3, 1 ],
+ "name" : "z"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 3, 3, 3, 5 ],
+ "className" : "str"
+ }
+ },
+ "value" : {
+ "kind" : "StringLiteral",
+ "location" : [ 3, 9, 3, 10 ],
+ "value" : ""
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 5, 1, 5, 5 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 5, 1, 5, 5 ],
+ "left" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 5, 1, 5, 1 ],
+ "value" : 1
+ },
+ "operator" : "+",
+ "right" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 5, 5, 5 ],
+ "name" : "x"
+ }
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 6, 1, 6, 9 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 6, 1, 6, 1 ],
+ "name" : "z"
+ } ],
+ "value" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 6, 5, 6, 9 ],
+ "left" : {
+ "kind" : "Identifier",
+ "location" : [ 6, 5, 6, 5 ],
+ "name" : "x"
+ },
+ "operator" : "+",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 9, 6, 9 ],
+ "value" : 1
+ }
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 7, 1, 7, 12 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 7, 1, 7, 1 ],
+ "name" : "z"
+ }, {
+ "kind" : "IndexExpr",
+ "location" : [ 7, 5, 7, 8 ],
+ "list" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 5, 7, 5 ],
+ "name" : "x"
+ },
+ "index" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 7, 7, 7, 7 ],
+ "value" : 0
+ }
+ } ],
+ "value" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 12, 7, 12 ],
+ "name" : "y"
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 8, 1, 8, 8 ],
+ "targets" : [ {
+ "kind" : "IndexExpr",
+ "location" : [ 8, 1, 8, 4 ],
+ "list" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 1, 8, 1 ],
+ "name" : "x"
+ },
+ "index" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 8, 3, 8, 3 ],
+ "value" : 1
+ }
+ } ],
+ "value" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 8, 8, 8 ],
+ "name" : "y"
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 9, 1, 9, 7 ],
+ "expr" : {
+ "kind" : "IndexExpr",
+ "location" : [ 9, 1, 9, 7 ],
+ "list" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 1, 9, 1 ],
+ "name" : "x"
+ },
+ "index" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 9, 3, 9, 6 ],
+ "value" : true
+ }
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_strings.py.ast.typed b/src/test/data/pa2/sample/bad_strings.py.ast.typed
new file mode 100644
index 0000000..f6f2fbe
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_strings.py.ast.typed
@@ -0,0 +1,301 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 9, 8 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 15 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 3, 1, 5 ],
+ "className" : "str"
+ }
+ },
+ "value" : {
+ "kind" : "StringLiteral",
+ "location" : [ 1, 9, 1, 15 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "value" : "Hello"
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 2, 1, 2, 15 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 1, 2, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 1, 2, 1 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 3, 2, 5 ],
+ "className" : "str"
+ }
+ },
+ "value" : {
+ "kind" : "StringLiteral",
+ "location" : [ 2, 9, 2, 15 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "value" : "World"
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 3, 1, 3, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 3, 1, 3, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 1, 3, 1 ],
+ "name" : "z"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 3, 3, 3, 5 ],
+ "className" : "str"
+ }
+ },
+ "value" : {
+ "kind" : "StringLiteral",
+ "location" : [ 3, 9, 3, 10 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "value" : ""
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 5, 1, 5, 5 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 5, 1, 5, 5 ],
+ "errorMsg" : "Cannot apply operator `+` on types `int` and `str`",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "left" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 5, 1, 5, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ },
+ "operator" : "+",
+ "right" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 5, 5, 5 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "name" : "x"
+ }
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 6, 1, 6, 9 ],
+ "errorMsg" : "Expected type `str`; got type `int`",
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 6, 1, 6, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "name" : "z"
+ } ],
+ "value" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 6, 5, 6, 9 ],
+ "errorMsg" : "Cannot apply operator `+` on types `str` and `int`",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "left" : {
+ "kind" : "Identifier",
+ "location" : [ 6, 5, 6, 5 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "name" : "x"
+ },
+ "operator" : "+",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 9, 6, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 7, 1, 7, 12 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 7, 1, 7, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "name" : "z"
+ }, {
+ "kind" : "IndexExpr",
+ "location" : [ 7, 5, 7, 8 ],
+ "errorMsg" : "`str` is not a list type",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "list" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 5, 7, 5 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "name" : "x"
+ },
+ "index" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 7, 7, 7, 7 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 0
+ }
+ } ],
+ "value" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 12, 7, 12 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "name" : "y"
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 8, 1, 8, 8 ],
+ "targets" : [ {
+ "kind" : "IndexExpr",
+ "location" : [ 8, 1, 8, 4 ],
+ "errorMsg" : "`str` is not a list type",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "list" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 1, 8, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "name" : "x"
+ },
+ "index" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 8, 3, 8, 3 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ } ],
+ "value" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 8, 8, 8 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "name" : "y"
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 9, 1, 9, 7 ],
+ "expr" : {
+ "kind" : "IndexExpr",
+ "location" : [ 9, 1, 9, 7 ],
+ "errorMsg" : "Index is of non-integer type `bool`",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "list" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 1, 9, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "name" : "x"
+ },
+ "index" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 9, 3, 9, 6 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : true
+ }
+ }
+ } ],
+ "errors" : {
+ "errors" : [ {
+ "kind" : "CompilerError",
+ "location" : [ 5, 1, 5, 5 ],
+ "message" : "Cannot apply operator `+` on types `int` and `str`"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 6, 5, 6, 9 ],
+ "message" : "Cannot apply operator `+` on types `str` and `int`"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 6, 1, 6, 9 ],
+ "message" : "Expected type `str`; got type `int`"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 7, 5, 7, 8 ],
+ "message" : "`str` is not a list type"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 8, 1, 8, 4 ],
+ "message" : "`str` is not a list type"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 9, 1, 9, 7 ],
+ "message" : "Index is of non-integer type `bool`"
+ } ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_type_annotation.py b/src/test/data/pa2/sample/bad_type_annotation.py
new file mode 100644
index 0000000..a25abb6
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_type_annotation.py
@@ -0,0 +1,7 @@
+x:A = None
+
+def foo(x:B) -> C:
+ y:D = None
+ return
+
+pass
diff --git a/src/test/data/pa2/sample/bad_type_annotation.py.ast b/src/test/data/pa2/sample/bad_type_annotation.py.ast
new file mode 100644
index 0000000..e42cf91
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_type_annotation.py.ast
@@ -0,0 +1,86 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 7, 5 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 3 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 3, 1, 3 ],
+ "className" : "A"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 1, 7, 1, 10 ]
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 3, 1, 5, 11 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 5, 3, 7 ],
+ "name" : "foo"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 3, 9, 3, 11 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 9, 3, 9 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 3, 11, 3, 11 ],
+ "className" : "B"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 3, 17, 3, 17 ],
+ "className" : "C"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 4, 5, 4, 14 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 4, 5, 4, 7 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 5, 4, 5 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 7, 4, 7 ],
+ "className" : "D"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 4, 11, 4, 14 ]
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 5, 5, 5, 10 ],
+ "value" : null
+ } ]
+ } ],
+ "statements" : [ ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_type_annotation.py.ast.typed b/src/test/data/pa2/sample/bad_type_annotation.py.ast.typed
new file mode 100644
index 0000000..221ad45
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_type_annotation.py.ast.typed
@@ -0,0 +1,106 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 7, 5 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 3 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 3, 1, 3 ],
+ "errorMsg" : "Invalid type annotation; there is no class named: A",
+ "className" : "A"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 1, 7, 1, 10 ]
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 3, 1, 5, 11 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 5, 3, 7 ],
+ "name" : "foo"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 3, 9, 3, 11 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 9, 3, 9 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 3, 11, 3, 11 ],
+ "errorMsg" : "Invalid type annotation; there is no class named: B",
+ "className" : "B"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 3, 17, 3, 17 ],
+ "errorMsg" : "Invalid type annotation; there is no class named: C",
+ "className" : "C"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 4, 5, 4, 14 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 4, 5, 4, 7 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 5, 4, 5 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 7, 4, 7 ],
+ "errorMsg" : "Invalid type annotation; there is no class named: D",
+ "className" : "D"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 4, 11, 4, 14 ]
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 5, 5, 5, 10 ],
+ "value" : null
+ } ]
+ } ],
+ "statements" : [ ],
+ "errors" : {
+ "errors" : [ {
+ "kind" : "CompilerError",
+ "location" : [ 1, 3, 1, 3 ],
+ "message" : "Invalid type annotation; there is no class named: A"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 3, 11, 3, 11 ],
+ "message" : "Invalid type annotation; there is no class named: B"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 3, 17, 3, 17 ],
+ "message" : "Invalid type annotation; there is no class named: C"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 4, 7, 4, 7 ],
+ "message" : "Invalid type annotation; there is no class named: D"
+ } ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_type_id.py b/src/test/data/pa2/sample/bad_type_id.py
new file mode 100644
index 0000000..0f931fb
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_type_id.py
@@ -0,0 +1 @@
+x - 1
diff --git a/src/test/data/pa2/sample/bad_type_id.py.ast b/src/test/data/pa2/sample/bad_type_id.py.ast
new file mode 100644
index 0000000..ff5c46d
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_type_id.py.ast
@@ -0,0 +1,29 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 1, 6 ],
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 1, 1, 1, 5 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 1, 1, 1, 5 ],
+ "left" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "operator" : "-",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 5, 1, 5 ],
+ "value" : 1
+ }
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_type_id.py.ast.typed b/src/test/data/pa2/sample/bad_type_id.py.ast.typed
new file mode 100644
index 0000000..5200116
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_type_id.py.ast.typed
@@ -0,0 +1,51 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 1, 6 ],
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 1, 1, 1, 5 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 1, 1, 1, 5 ],
+ "errorMsg" : "Cannot apply operator `-` on types `object` and `int`",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "left" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "errorMsg" : "Not a variable: x",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ },
+ "name" : "x"
+ },
+ "operator" : "-",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 5, 1, 5 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ }
+ } ],
+ "errors" : {
+ "errors" : [ {
+ "kind" : "CompilerError",
+ "location" : [ 1, 1, 1, 1 ],
+ "message" : "Not a variable: x"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 1, 1, 1, 5 ],
+ "message" : "Cannot apply operator `-` on types `object` and `int`"
+ } ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_var_assign.py b/src/test/data/pa2/sample/bad_var_assign.py
new file mode 100644
index 0000000..a383775
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_var_assign.py
@@ -0,0 +1,8 @@
+x:int = 1
+y:bool = True
+
+x = False
+y = 2
+z = 3
+x = z = 4
+x = z = None
diff --git a/src/test/data/pa2/sample/bad_var_assign.py.ast b/src/test/data/pa2/sample/bad_var_assign.py.ast
new file mode 100644
index 0000000..6dabcbd
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_var_assign.py.ast
@@ -0,0 +1,127 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 8, 13 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 3, 1, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 9, 1, 9 ],
+ "value" : 1
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 2, 1, 2, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 1, 2, 6 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 1, 2, 1 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 3, 2, 6 ],
+ "className" : "bool"
+ }
+ },
+ "value" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 2, 10, 2, 13 ],
+ "value" : true
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 4, 1, 4, 9 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 4, 1, 4, 1 ],
+ "name" : "x"
+ } ],
+ "value" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 4, 5, 4, 9 ],
+ "value" : false
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 5, 1, 5, 5 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 5, 1, 5, 1 ],
+ "name" : "y"
+ } ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 5, 5, 5, 5 ],
+ "value" : 2
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 6, 1, 6, 5 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 6, 1, 6, 1 ],
+ "name" : "z"
+ } ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 5, 6, 5 ],
+ "value" : 3
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 7, 1, 7, 9 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 7, 1, 7, 1 ],
+ "name" : "x"
+ }, {
+ "kind" : "Identifier",
+ "location" : [ 7, 5, 7, 5 ],
+ "name" : "z"
+ } ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 7, 9, 7, 9 ],
+ "value" : 4
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 8, 1, 8, 12 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 8, 1, 8, 1 ],
+ "name" : "x"
+ }, {
+ "kind" : "Identifier",
+ "location" : [ 8, 5, 8, 5 ],
+ "name" : "z"
+ } ],
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 8, 9, 8, 12 ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/bad_var_assign.py.ast.typed b/src/test/data/pa2/sample/bad_var_assign.py.ast.typed
new file mode 100644
index 0000000..d8217b8
--- /dev/null
+++ b/src/test/data/pa2/sample/bad_var_assign.py.ast.typed
@@ -0,0 +1,213 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 8, 13 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 3, 1, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 9, 1, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 2, 1, 2, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 1, 2, 6 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 1, 2, 1 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 3, 2, 6 ],
+ "className" : "bool"
+ }
+ },
+ "value" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 2, 10, 2, 13 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : true
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 4, 1, 4, 9 ],
+ "errorMsg" : "Expected type `int`; got type `bool`",
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 4, 1, 4, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "x"
+ } ],
+ "value" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 4, 5, 4, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : false
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 5, 1, 5, 5 ],
+ "errorMsg" : "Expected type `bool`; got type `int`",
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 5, 1, 5, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "name" : "y"
+ } ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 5, 5, 5, 5 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 2
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 6, 1, 6, 5 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 6, 1, 6, 1 ],
+ "errorMsg" : "Not a variable: z",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ },
+ "name" : "z"
+ } ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 5, 6, 5 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 3
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 7, 1, 7, 9 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 7, 1, 7, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "x"
+ }, {
+ "kind" : "Identifier",
+ "location" : [ 7, 5, 7, 5 ],
+ "errorMsg" : "Not a variable: z",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ },
+ "name" : "z"
+ } ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 7, 9, 7, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 4
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 8, 1, 8, 12 ],
+ "errorMsg" : "Expected type `int`; got type ``",
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 8, 1, 8, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "x"
+ }, {
+ "kind" : "Identifier",
+ "location" : [ 8, 5, 8, 5 ],
+ "errorMsg" : "Not a variable: z",
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ },
+ "name" : "z"
+ } ],
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 8, 9, 8, 12 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ } ],
+ "errors" : {
+ "errors" : [ {
+ "kind" : "CompilerError",
+ "location" : [ 4, 1, 4, 9 ],
+ "message" : "Expected type `int`; got type `bool`"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 5, 1, 5, 5 ],
+ "message" : "Expected type `bool`; got type `int`"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 6, 1, 6, 1 ],
+ "message" : "Not a variable: z"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 7, 5, 7, 5 ],
+ "message" : "Not a variable: z"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 8, 1, 8, 12 ],
+ "message" : "Expected type `int`; got type ``"
+ }, {
+ "kind" : "CompilerError",
+ "location" : [ 8, 5, 8, 5 ],
+ "message" : "Not a variable: z"
+ } ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/class_def_assign.py b/src/test/data/pa2/sample/class_def_assign.py
new file mode 100644
index 0000000..44459ff
--- /dev/null
+++ b/src/test/data/pa2/sample/class_def_assign.py
@@ -0,0 +1,18 @@
+class A(object):
+ x:int = 1
+
+class B(A):
+ def __init__(self: "B"):
+ pass
+
+class C(B):
+ z:bool = True
+
+a:A = None
+b:B = None
+c:C = None
+
+a = A()
+a = B()
+b = a = c = C()
+c = None
diff --git a/src/test/data/pa2/sample/class_def_assign.py.ast b/src/test/data/pa2/sample/class_def_assign.py.ast
new file mode 100644
index 0000000..92ae3a1
--- /dev/null
+++ b/src/test/data/pa2/sample/class_def_assign.py.ast
@@ -0,0 +1,263 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 18, 9 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 1, 1, 2, 14 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 7, 1, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 2, 5, 2, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 5, 2, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 5, 2, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 7, 2, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 13, 2, 13 ],
+ "value" : 1
+ }
+ } ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 4, 1, 8, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 7, 4, 7 ],
+ "name" : "B"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 9, 4, 9 ],
+ "name" : "A"
+ },
+ "declarations" : [ {
+ "kind" : "FuncDef",
+ "location" : [ 5, 5, 6, 13 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 9, 5, 16 ],
+ "name" : "__init__"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 5, 18, 5, 26 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 18, 5, 21 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 24, 5, 26 ],
+ "className" : "B"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 28, 5, 28 ],
+ "className" : ""
+ },
+ "declarations" : [ ],
+ "statements" : [ ]
+ } ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 8, 1, 9, 18 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 7, 8, 7 ],
+ "name" : "C"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 9, 8, 9 ],
+ "name" : "B"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 9, 5, 9, 17 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 9, 5, 9, 10 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 5, 9, 5 ],
+ "name" : "z"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 9, 7, 9, 10 ],
+ "className" : "bool"
+ }
+ },
+ "value" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 9, 14, 9, 17 ],
+ "value" : true
+ }
+ } ]
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 11, 1, 11, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 11, 1, 11, 3 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 1, 11, 1 ],
+ "name" : "a"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 11, 3, 11, 3 ],
+ "className" : "A"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 11, 7, 11, 10 ]
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 12, 1, 12, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 12, 1, 12, 3 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 12, 1, 12, 1 ],
+ "name" : "b"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 12, 3, 12, 3 ],
+ "className" : "B"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 12, 7, 12, 10 ]
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 13, 1, 13, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 13, 1, 13, 3 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 13, 1, 13, 1 ],
+ "name" : "c"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 13, 3, 13, 3 ],
+ "className" : "C"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 13, 7, 13, 10 ]
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 15, 1, 15, 7 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 15, 1, 15, 1 ],
+ "name" : "a"
+ } ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 15, 5, 15, 7 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 15, 5, 15, 5 ],
+ "name" : "A"
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 16, 1, 16, 7 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 16, 1, 16, 1 ],
+ "name" : "a"
+ } ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 16, 5, 16, 7 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 16, 5, 16, 5 ],
+ "name" : "B"
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 17, 1, 17, 15 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 17, 1, 17, 1 ],
+ "name" : "b"
+ }, {
+ "kind" : "Identifier",
+ "location" : [ 17, 5, 17, 5 ],
+ "name" : "a"
+ }, {
+ "kind" : "Identifier",
+ "location" : [ 17, 9, 17, 9 ],
+ "name" : "c"
+ } ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 17, 13, 17, 15 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 17, 13, 17, 13 ],
+ "name" : "C"
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 18, 1, 18, 8 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 18, 1, 18, 1 ],
+ "name" : "c"
+ } ],
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 18, 5, 18, 8 ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/class_def_assign.py.ast.typed b/src/test/data/pa2/sample/class_def_assign.py.ast.typed
new file mode 100644
index 0000000..e012a95
--- /dev/null
+++ b/src/test/data/pa2/sample/class_def_assign.py.ast.typed
@@ -0,0 +1,323 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 18, 9 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 1, 1, 2, 14 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 7, 1, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 2, 5, 2, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 5, 2, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 5, 2, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 7, 2, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 13, 2, 13 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ } ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 4, 1, 8, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 7, 4, 7 ],
+ "name" : "B"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 9, 4, 9 ],
+ "name" : "A"
+ },
+ "declarations" : [ {
+ "kind" : "FuncDef",
+ "location" : [ 5, 5, 6, 13 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 9, 5, 16 ],
+ "name" : "__init__"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 5, 18, 5, 26 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 18, 5, 21 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 24, 5, 26 ],
+ "className" : "B"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 28, 5, 28 ],
+ "className" : ""
+ },
+ "declarations" : [ ],
+ "statements" : [ ]
+ } ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 8, 1, 9, 18 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 7, 8, 7 ],
+ "name" : "C"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 9, 8, 9 ],
+ "name" : "B"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 9, 5, 9, 17 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 9, 5, 9, 10 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 5, 9, 5 ],
+ "name" : "z"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 9, 7, 9, 10 ],
+ "className" : "bool"
+ }
+ },
+ "value" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 9, 14, 9, 17 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : true
+ }
+ } ]
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 11, 1, 11, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 11, 1, 11, 3 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 1, 11, 1 ],
+ "name" : "a"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 11, 3, 11, 3 ],
+ "className" : "A"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 11, 7, 11, 10 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 12, 1, 12, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 12, 1, 12, 3 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 12, 1, 12, 1 ],
+ "name" : "b"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 12, 3, 12, 3 ],
+ "className" : "B"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 12, 7, 12, 10 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 13, 1, 13, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 13, 1, 13, 3 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 13, 1, 13, 1 ],
+ "name" : "c"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 13, 3, 13, 3 ],
+ "className" : "C"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 13, 7, 13, 10 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 15, 1, 15, 7 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 15, 1, 15, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "A"
+ },
+ "name" : "a"
+ } ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 15, 5, 15, 7 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "A"
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 15, 5, 15, 5 ],
+ "name" : "A"
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 16, 1, 16, 7 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 16, 1, 16, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "A"
+ },
+ "name" : "a"
+ } ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 16, 5, 16, 7 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "B"
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 16, 5, 16, 5 ],
+ "name" : "B"
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 17, 1, 17, 15 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 17, 1, 17, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "B"
+ },
+ "name" : "b"
+ }, {
+ "kind" : "Identifier",
+ "location" : [ 17, 5, 17, 5 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "A"
+ },
+ "name" : "a"
+ }, {
+ "kind" : "Identifier",
+ "location" : [ 17, 9, 17, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "C"
+ },
+ "name" : "c"
+ } ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 17, 13, 17, 15 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "C"
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 17, 13, 17, 13 ],
+ "name" : "C"
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 18, 1, 18, 8 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 18, 1, 18, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "C"
+ },
+ "name" : "c"
+ } ],
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 18, 5, 18, 8 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/class_def_attr.py b/src/test/data/pa2/sample/class_def_attr.py
new file mode 100644
index 0000000..9a5d948
--- /dev/null
+++ b/src/test/data/pa2/sample/class_def_attr.py
@@ -0,0 +1,22 @@
+class A(object):
+ x:int = 1
+
+class B(A):
+ def __init__(self: "B"):
+ pass
+
+class C(B):
+ z:bool = True
+
+a:A = None
+b:B = None
+c:C = None
+
+a = A()
+b = B()
+c = C()
+
+a.x = 1
+b.x = a.x
+c.z = a.x == b.x
+
diff --git a/src/test/data/pa2/sample/class_def_attr.py.ast b/src/test/data/pa2/sample/class_def_attr.py.ast
new file mode 100644
index 0000000..b4dcc19
--- /dev/null
+++ b/src/test/data/pa2/sample/class_def_attr.py.ast
@@ -0,0 +1,346 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 21, 17 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 1, 1, 2, 14 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 7, 1, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 2, 5, 2, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 5, 2, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 5, 2, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 7, 2, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 13, 2, 13 ],
+ "value" : 1
+ }
+ } ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 4, 1, 8, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 7, 4, 7 ],
+ "name" : "B"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 9, 4, 9 ],
+ "name" : "A"
+ },
+ "declarations" : [ {
+ "kind" : "FuncDef",
+ "location" : [ 5, 5, 6, 13 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 9, 5, 16 ],
+ "name" : "__init__"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 5, 18, 5, 26 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 18, 5, 21 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 24, 5, 26 ],
+ "className" : "B"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 28, 5, 28 ],
+ "className" : ""
+ },
+ "declarations" : [ ],
+ "statements" : [ ]
+ } ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 8, 1, 9, 18 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 7, 8, 7 ],
+ "name" : "C"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 9, 8, 9 ],
+ "name" : "B"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 9, 5, 9, 17 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 9, 5, 9, 10 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 5, 9, 5 ],
+ "name" : "z"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 9, 7, 9, 10 ],
+ "className" : "bool"
+ }
+ },
+ "value" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 9, 14, 9, 17 ],
+ "value" : true
+ }
+ } ]
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 11, 1, 11, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 11, 1, 11, 3 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 1, 11, 1 ],
+ "name" : "a"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 11, 3, 11, 3 ],
+ "className" : "A"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 11, 7, 11, 10 ]
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 12, 1, 12, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 12, 1, 12, 3 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 12, 1, 12, 1 ],
+ "name" : "b"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 12, 3, 12, 3 ],
+ "className" : "B"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 12, 7, 12, 10 ]
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 13, 1, 13, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 13, 1, 13, 3 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 13, 1, 13, 1 ],
+ "name" : "c"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 13, 3, 13, 3 ],
+ "className" : "C"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 13, 7, 13, 10 ]
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 15, 1, 15, 7 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 15, 1, 15, 1 ],
+ "name" : "a"
+ } ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 15, 5, 15, 7 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 15, 5, 15, 5 ],
+ "name" : "A"
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 16, 1, 16, 7 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 16, 1, 16, 1 ],
+ "name" : "b"
+ } ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 16, 5, 16, 7 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 16, 5, 16, 5 ],
+ "name" : "B"
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 17, 1, 17, 7 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 17, 1, 17, 1 ],
+ "name" : "c"
+ } ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 17, 5, 17, 7 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 17, 5, 17, 5 ],
+ "name" : "C"
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 19, 1, 19, 7 ],
+ "targets" : [ {
+ "kind" : "MemberExpr",
+ "location" : [ 19, 1, 19, 3 ],
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 19, 1, 19, 1 ],
+ "name" : "a"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 19, 3, 19, 3 ],
+ "name" : "x"
+ }
+ } ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 19, 7, 19, 7 ],
+ "value" : 1
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 20, 1, 20, 9 ],
+ "targets" : [ {
+ "kind" : "MemberExpr",
+ "location" : [ 20, 1, 20, 3 ],
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 20, 1, 20, 1 ],
+ "name" : "b"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 20, 3, 20, 3 ],
+ "name" : "x"
+ }
+ } ],
+ "value" : {
+ "kind" : "MemberExpr",
+ "location" : [ 20, 7, 20, 9 ],
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 20, 7, 20, 7 ],
+ "name" : "a"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 20, 9, 20, 9 ],
+ "name" : "x"
+ }
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 21, 1, 21, 16 ],
+ "targets" : [ {
+ "kind" : "MemberExpr",
+ "location" : [ 21, 1, 21, 3 ],
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 21, 1, 21, 1 ],
+ "name" : "c"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 21, 3, 21, 3 ],
+ "name" : "z"
+ }
+ } ],
+ "value" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 21, 7, 21, 16 ],
+ "left" : {
+ "kind" : "MemberExpr",
+ "location" : [ 21, 7, 21, 9 ],
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 21, 7, 21, 7 ],
+ "name" : "a"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 21, 9, 21, 9 ],
+ "name" : "x"
+ }
+ },
+ "operator" : "==",
+ "right" : {
+ "kind" : "MemberExpr",
+ "location" : [ 21, 14, 21, 16 ],
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 21, 14, 21, 14 ],
+ "name" : "b"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 21, 16, 21, 16 ],
+ "name" : "x"
+ }
+ }
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/class_def_attr.py.ast.typed b/src/test/data/pa2/sample/class_def_attr.py.ast.typed
new file mode 100644
index 0000000..600032c
--- /dev/null
+++ b/src/test/data/pa2/sample/class_def_attr.py.ast.typed
@@ -0,0 +1,446 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 21, 17 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 1, 1, 2, 14 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 7, 1, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 2, 5, 2, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 5, 2, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 5, 2, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 7, 2, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 13, 2, 13 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ } ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 4, 1, 8, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 7, 4, 7 ],
+ "name" : "B"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 9, 4, 9 ],
+ "name" : "A"
+ },
+ "declarations" : [ {
+ "kind" : "FuncDef",
+ "location" : [ 5, 5, 6, 13 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 9, 5, 16 ],
+ "name" : "__init__"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 5, 18, 5, 26 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 18, 5, 21 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 24, 5, 26 ],
+ "className" : "B"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 28, 5, 28 ],
+ "className" : ""
+ },
+ "declarations" : [ ],
+ "statements" : [ ]
+ } ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 8, 1, 9, 18 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 7, 8, 7 ],
+ "name" : "C"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 9, 8, 9 ],
+ "name" : "B"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 9, 5, 9, 17 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 9, 5, 9, 10 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 5, 9, 5 ],
+ "name" : "z"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 9, 7, 9, 10 ],
+ "className" : "bool"
+ }
+ },
+ "value" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 9, 14, 9, 17 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : true
+ }
+ } ]
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 11, 1, 11, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 11, 1, 11, 3 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 1, 11, 1 ],
+ "name" : "a"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 11, 3, 11, 3 ],
+ "className" : "A"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 11, 7, 11, 10 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 12, 1, 12, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 12, 1, 12, 3 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 12, 1, 12, 1 ],
+ "name" : "b"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 12, 3, 12, 3 ],
+ "className" : "B"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 12, 7, 12, 10 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 13, 1, 13, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 13, 1, 13, 3 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 13, 1, 13, 1 ],
+ "name" : "c"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 13, 3, 13, 3 ],
+ "className" : "C"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 13, 7, 13, 10 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 15, 1, 15, 7 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 15, 1, 15, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "A"
+ },
+ "name" : "a"
+ } ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 15, 5, 15, 7 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "A"
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 15, 5, 15, 5 ],
+ "name" : "A"
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 16, 1, 16, 7 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 16, 1, 16, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "B"
+ },
+ "name" : "b"
+ } ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 16, 5, 16, 7 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "B"
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 16, 5, 16, 5 ],
+ "name" : "B"
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 17, 1, 17, 7 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 17, 1, 17, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "C"
+ },
+ "name" : "c"
+ } ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 17, 5, 17, 7 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "C"
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 17, 5, 17, 5 ],
+ "name" : "C"
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 19, 1, 19, 7 ],
+ "targets" : [ {
+ "kind" : "MemberExpr",
+ "location" : [ 19, 1, 19, 3 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 19, 1, 19, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "A"
+ },
+ "name" : "a"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 19, 3, 19, 3 ],
+ "name" : "x"
+ }
+ } ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 19, 7, 19, 7 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 20, 1, 20, 9 ],
+ "targets" : [ {
+ "kind" : "MemberExpr",
+ "location" : [ 20, 1, 20, 3 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 20, 1, 20, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "B"
+ },
+ "name" : "b"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 20, 3, 20, 3 ],
+ "name" : "x"
+ }
+ } ],
+ "value" : {
+ "kind" : "MemberExpr",
+ "location" : [ 20, 7, 20, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 20, 7, 20, 7 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "A"
+ },
+ "name" : "a"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 20, 9, 20, 9 ],
+ "name" : "x"
+ }
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 21, 1, 21, 16 ],
+ "targets" : [ {
+ "kind" : "MemberExpr",
+ "location" : [ 21, 1, 21, 3 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 21, 1, 21, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "C"
+ },
+ "name" : "c"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 21, 3, 21, 3 ],
+ "name" : "z"
+ }
+ } ],
+ "value" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 21, 7, 21, 16 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "left" : {
+ "kind" : "MemberExpr",
+ "location" : [ 21, 7, 21, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 21, 7, 21, 7 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "A"
+ },
+ "name" : "a"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 21, 9, 21, 9 ],
+ "name" : "x"
+ }
+ },
+ "operator" : "==",
+ "right" : {
+ "kind" : "MemberExpr",
+ "location" : [ 21, 14, 21, 16 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 21, 14, 21, 14 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "B"
+ },
+ "name" : "b"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 21, 16, 21, 16 ],
+ "name" : "x"
+ }
+ }
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/class_def_init.py b/src/test/data/pa2/sample/class_def_init.py
new file mode 100644
index 0000000..733f489
--- /dev/null
+++ b/src/test/data/pa2/sample/class_def_init.py
@@ -0,0 +1,17 @@
+class A(object):
+ x:int = 1
+
+class B(A):
+ def __init__(self: "B"):
+ pass
+
+class C(B):
+ z:bool = True
+
+a:A = None
+b:B = None
+c:C = None
+
+a = A()
+b = B()
+c = C()
diff --git a/src/test/data/pa2/sample/class_def_init.py.ast b/src/test/data/pa2/sample/class_def_init.py.ast
new file mode 100644
index 0000000..2cf1bba
--- /dev/null
+++ b/src/test/data/pa2/sample/class_def_init.py.ast
@@ -0,0 +1,243 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 17, 8 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 1, 1, 2, 14 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 7, 1, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 2, 5, 2, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 5, 2, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 5, 2, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 7, 2, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 13, 2, 13 ],
+ "value" : 1
+ }
+ } ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 4, 1, 8, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 7, 4, 7 ],
+ "name" : "B"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 9, 4, 9 ],
+ "name" : "A"
+ },
+ "declarations" : [ {
+ "kind" : "FuncDef",
+ "location" : [ 5, 5, 6, 13 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 9, 5, 16 ],
+ "name" : "__init__"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 5, 18, 5, 26 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 18, 5, 21 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 24, 5, 26 ],
+ "className" : "B"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 28, 5, 28 ],
+ "className" : ""
+ },
+ "declarations" : [ ],
+ "statements" : [ ]
+ } ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 8, 1, 9, 18 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 7, 8, 7 ],
+ "name" : "C"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 9, 8, 9 ],
+ "name" : "B"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 9, 5, 9, 17 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 9, 5, 9, 10 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 5, 9, 5 ],
+ "name" : "z"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 9, 7, 9, 10 ],
+ "className" : "bool"
+ }
+ },
+ "value" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 9, 14, 9, 17 ],
+ "value" : true
+ }
+ } ]
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 11, 1, 11, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 11, 1, 11, 3 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 1, 11, 1 ],
+ "name" : "a"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 11, 3, 11, 3 ],
+ "className" : "A"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 11, 7, 11, 10 ]
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 12, 1, 12, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 12, 1, 12, 3 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 12, 1, 12, 1 ],
+ "name" : "b"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 12, 3, 12, 3 ],
+ "className" : "B"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 12, 7, 12, 10 ]
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 13, 1, 13, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 13, 1, 13, 3 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 13, 1, 13, 1 ],
+ "name" : "c"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 13, 3, 13, 3 ],
+ "className" : "C"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 13, 7, 13, 10 ]
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 15, 1, 15, 7 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 15, 1, 15, 1 ],
+ "name" : "a"
+ } ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 15, 5, 15, 7 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 15, 5, 15, 5 ],
+ "name" : "A"
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 16, 1, 16, 7 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 16, 1, 16, 1 ],
+ "name" : "b"
+ } ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 16, 5, 16, 7 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 16, 5, 16, 5 ],
+ "name" : "B"
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 17, 1, 17, 7 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 17, 1, 17, 1 ],
+ "name" : "c"
+ } ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 17, 5, 17, 7 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 17, 5, 17, 5 ],
+ "name" : "C"
+ },
+ "args" : [ ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/class_def_init.py.ast.typed b/src/test/data/pa2/sample/class_def_init.py.ast.typed
new file mode 100644
index 0000000..c2f9d72
--- /dev/null
+++ b/src/test/data/pa2/sample/class_def_init.py.ast.typed
@@ -0,0 +1,287 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 17, 8 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 1, 1, 2, 14 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 7, 1, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 2, 5, 2, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 5, 2, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 5, 2, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 7, 2, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 13, 2, 13 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ } ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 4, 1, 8, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 7, 4, 7 ],
+ "name" : "B"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 9, 4, 9 ],
+ "name" : "A"
+ },
+ "declarations" : [ {
+ "kind" : "FuncDef",
+ "location" : [ 5, 5, 6, 13 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 9, 5, 16 ],
+ "name" : "__init__"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 5, 18, 5, 26 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 18, 5, 21 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 24, 5, 26 ],
+ "className" : "B"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 5, 28, 5, 28 ],
+ "className" : ""
+ },
+ "declarations" : [ ],
+ "statements" : [ ]
+ } ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 8, 1, 9, 18 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 7, 8, 7 ],
+ "name" : "C"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 9, 8, 9 ],
+ "name" : "B"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 9, 5, 9, 17 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 9, 5, 9, 10 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 5, 9, 5 ],
+ "name" : "z"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 9, 7, 9, 10 ],
+ "className" : "bool"
+ }
+ },
+ "value" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 9, 14, 9, 17 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : true
+ }
+ } ]
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 11, 1, 11, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 11, 1, 11, 3 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 1, 11, 1 ],
+ "name" : "a"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 11, 3, 11, 3 ],
+ "className" : "A"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 11, 7, 11, 10 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 12, 1, 12, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 12, 1, 12, 3 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 12, 1, 12, 1 ],
+ "name" : "b"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 12, 3, 12, 3 ],
+ "className" : "B"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 12, 7, 12, 10 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 13, 1, 13, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 13, 1, 13, 3 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 13, 1, 13, 1 ],
+ "name" : "c"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 13, 3, 13, 3 ],
+ "className" : "C"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 13, 7, 13, 10 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 15, 1, 15, 7 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 15, 1, 15, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "A"
+ },
+ "name" : "a"
+ } ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 15, 5, 15, 7 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "A"
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 15, 5, 15, 5 ],
+ "name" : "A"
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 16, 1, 16, 7 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 16, 1, 16, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "B"
+ },
+ "name" : "b"
+ } ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 16, 5, 16, 7 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "B"
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 16, 5, 16, 5 ],
+ "name" : "B"
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 17, 1, 17, 7 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 17, 1, 17, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "C"
+ },
+ "name" : "c"
+ } ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 17, 5, 17, 7 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "C"
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 17, 5, 17, 5 ],
+ "name" : "C"
+ },
+ "args" : [ ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/class_def_methods.py b/src/test/data/pa2/sample/class_def_methods.py
new file mode 100644
index 0000000..a8d70f1
--- /dev/null
+++ b/src/test/data/pa2/sample/class_def_methods.py
@@ -0,0 +1,28 @@
+class A(object):
+ x:int = 1
+
+ def get_A(self: "A") -> int:
+ return self.x
+
+class B(A):
+ def __init__(self: "B"):
+ pass
+
+class C(B):
+ z:bool = True
+
+ def set_A(self: "C", val: int) -> object:
+ self.x = val
+
+a:A = None
+b:B = None
+c:C = None
+
+a = A()
+b = B()
+c = C()
+
+b.x = a.get_A()
+a.x = b.get_A()
+c.set_A(0)
+
diff --git a/src/test/data/pa2/sample/class_def_methods.py.ast b/src/test/data/pa2/sample/class_def_methods.py.ast
new file mode 100644
index 0000000..2ddc48e
--- /dev/null
+++ b/src/test/data/pa2/sample/class_def_methods.py.ast
@@ -0,0 +1,451 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 27, 11 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 1, 1, 7, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 7, 1, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 2, 5, 2, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 5, 2, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 5, 2, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 7, 2, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 13, 2, 13 ],
+ "value" : 1
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 4, 5, 5, 22 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 9, 4, 13 ],
+ "name" : "get_A"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 4, 15, 4, 23 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 15, 4, 18 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 21, 4, 23 ],
+ "className" : "A"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 29, 4, 31 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 5, 9, 5, 21 ],
+ "value" : {
+ "kind" : "MemberExpr",
+ "location" : [ 5, 16, 5, 21 ],
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 16, 5, 19 ],
+ "name" : "self"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 21, 5, 21 ],
+ "name" : "x"
+ }
+ }
+ } ]
+ } ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 7, 1, 11, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 7, 7, 7 ],
+ "name" : "B"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 9, 7, 9 ],
+ "name" : "A"
+ },
+ "declarations" : [ {
+ "kind" : "FuncDef",
+ "location" : [ 8, 5, 9, 13 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 9, 8, 16 ],
+ "name" : "__init__"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 8, 18, 8, 26 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 18, 8, 21 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 8, 24, 8, 26 ],
+ "className" : "B"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 8, 28, 8, 28 ],
+ "className" : ""
+ },
+ "declarations" : [ ],
+ "statements" : [ ]
+ } ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 11, 1, 17, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 7, 11, 7 ],
+ "name" : "C"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 9, 11, 9 ],
+ "name" : "B"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 12, 5, 12, 17 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 12, 5, 12, 10 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 12, 5, 12, 5 ],
+ "name" : "z"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 12, 7, 12, 10 ],
+ "className" : "bool"
+ }
+ },
+ "value" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 12, 14, 12, 17 ],
+ "value" : true
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 14, 5, 15, 21 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 14, 9, 14, 13 ],
+ "name" : "set_A"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 14, 15, 14, 23 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 14, 15, 14, 18 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 14, 21, 14, 23 ],
+ "className" : "C"
+ }
+ }, {
+ "kind" : "TypedVar",
+ "location" : [ 14, 26, 14, 33 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 14, 26, 14, 28 ],
+ "name" : "val"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 14, 31, 14, 33 ],
+ "className" : "int"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 14, 39, 14, 44 ],
+ "className" : "object"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 15, 9, 15, 20 ],
+ "targets" : [ {
+ "kind" : "MemberExpr",
+ "location" : [ 15, 9, 15, 14 ],
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 15, 9, 15, 12 ],
+ "name" : "self"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 15, 14, 15, 14 ],
+ "name" : "x"
+ }
+ } ],
+ "value" : {
+ "kind" : "Identifier",
+ "location" : [ 15, 18, 15, 20 ],
+ "name" : "val"
+ }
+ } ]
+ } ]
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 17, 1, 17, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 17, 1, 17, 3 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 17, 1, 17, 1 ],
+ "name" : "a"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 17, 3, 17, 3 ],
+ "className" : "A"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 17, 7, 17, 10 ]
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 18, 1, 18, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 18, 1, 18, 3 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 18, 1, 18, 1 ],
+ "name" : "b"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 18, 3, 18, 3 ],
+ "className" : "B"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 18, 7, 18, 10 ]
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 19, 1, 19, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 19, 1, 19, 3 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 19, 1, 19, 1 ],
+ "name" : "c"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 19, 3, 19, 3 ],
+ "className" : "C"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 19, 7, 19, 10 ]
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 21, 1, 21, 7 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 21, 1, 21, 1 ],
+ "name" : "a"
+ } ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 21, 5, 21, 7 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 21, 5, 21, 5 ],
+ "name" : "A"
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 22, 1, 22, 7 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 22, 1, 22, 1 ],
+ "name" : "b"
+ } ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 22, 5, 22, 7 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 22, 5, 22, 5 ],
+ "name" : "B"
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 23, 1, 23, 7 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 23, 1, 23, 1 ],
+ "name" : "c"
+ } ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 23, 5, 23, 7 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 23, 5, 23, 5 ],
+ "name" : "C"
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 25, 1, 25, 15 ],
+ "targets" : [ {
+ "kind" : "MemberExpr",
+ "location" : [ 25, 1, 25, 3 ],
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 25, 1, 25, 1 ],
+ "name" : "b"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 25, 3, 25, 3 ],
+ "name" : "x"
+ }
+ } ],
+ "value" : {
+ "kind" : "MethodCallExpr",
+ "location" : [ 25, 7, 25, 15 ],
+ "method" : {
+ "kind" : "MemberExpr",
+ "location" : [ 25, 7, 25, 13 ],
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 25, 7, 25, 7 ],
+ "name" : "a"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 25, 9, 25, 13 ],
+ "name" : "get_A"
+ }
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 26, 1, 26, 15 ],
+ "targets" : [ {
+ "kind" : "MemberExpr",
+ "location" : [ 26, 1, 26, 3 ],
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 26, 1, 26, 1 ],
+ "name" : "a"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 26, 3, 26, 3 ],
+ "name" : "x"
+ }
+ } ],
+ "value" : {
+ "kind" : "MethodCallExpr",
+ "location" : [ 26, 7, 26, 15 ],
+ "method" : {
+ "kind" : "MemberExpr",
+ "location" : [ 26, 7, 26, 13 ],
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 26, 7, 26, 7 ],
+ "name" : "b"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 26, 9, 26, 13 ],
+ "name" : "get_A"
+ }
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 27, 1, 27, 10 ],
+ "expr" : {
+ "kind" : "MethodCallExpr",
+ "location" : [ 27, 1, 27, 10 ],
+ "method" : {
+ "kind" : "MemberExpr",
+ "location" : [ 27, 1, 27, 7 ],
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 27, 1, 27, 1 ],
+ "name" : "c"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 27, 3, 27, 7 ],
+ "name" : "set_A"
+ }
+ },
+ "args" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 27, 9, 27, 9 ],
+ "value" : 0
+ } ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/class_def_methods.py.ast.typed b/src/test/data/pa2/sample/class_def_methods.py.ast.typed
new file mode 100644
index 0000000..1f58660
--- /dev/null
+++ b/src/test/data/pa2/sample/class_def_methods.py.ast.typed
@@ -0,0 +1,595 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 27, 11 ],
+ "declarations" : [ {
+ "kind" : "ClassDef",
+ "location" : [ 1, 1, 7, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 7, 1, 7 ],
+ "name" : "A"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 14 ],
+ "name" : "object"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 2, 5, 2, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 5, 2, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 5, 2, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 7, 2, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 13, 2, 13 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 4, 5, 5, 22 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 9, 4, 13 ],
+ "name" : "get_A"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 4, 15, 4, 23 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 15, 4, 18 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 21, 4, 23 ],
+ "className" : "A"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 29, 4, 31 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 5, 9, 5, 21 ],
+ "value" : {
+ "kind" : "MemberExpr",
+ "location" : [ 5, 16, 5, 21 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 16, 5, 19 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "A"
+ },
+ "name" : "self"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 21, 5, 21 ],
+ "name" : "x"
+ }
+ }
+ } ]
+ } ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 7, 1, 11, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 7, 7, 7 ],
+ "name" : "B"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 9, 7, 9 ],
+ "name" : "A"
+ },
+ "declarations" : [ {
+ "kind" : "FuncDef",
+ "location" : [ 8, 5, 9, 13 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 9, 8, 16 ],
+ "name" : "__init__"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 8, 18, 8, 26 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 18, 8, 21 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 8, 24, 8, 26 ],
+ "className" : "B"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 8, 28, 8, 28 ],
+ "className" : ""
+ },
+ "declarations" : [ ],
+ "statements" : [ ]
+ } ]
+ }, {
+ "kind" : "ClassDef",
+ "location" : [ 11, 1, 17, 0 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 7, 11, 7 ],
+ "name" : "C"
+ },
+ "superClass" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 9, 11, 9 ],
+ "name" : "B"
+ },
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 12, 5, 12, 17 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 12, 5, 12, 10 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 12, 5, 12, 5 ],
+ "name" : "z"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 12, 7, 12, 10 ],
+ "className" : "bool"
+ }
+ },
+ "value" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 12, 14, 12, 17 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : true
+ }
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 14, 5, 15, 21 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 14, 9, 14, 13 ],
+ "name" : "set_A"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 14, 15, 14, 23 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 14, 15, 14, 18 ],
+ "name" : "self"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 14, 21, 14, 23 ],
+ "className" : "C"
+ }
+ }, {
+ "kind" : "TypedVar",
+ "location" : [ 14, 26, 14, 33 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 14, 26, 14, 28 ],
+ "name" : "val"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 14, 31, 14, 33 ],
+ "className" : "int"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 14, 39, 14, 44 ],
+ "className" : "object"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 15, 9, 15, 20 ],
+ "targets" : [ {
+ "kind" : "MemberExpr",
+ "location" : [ 15, 9, 15, 14 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 15, 9, 15, 12 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "C"
+ },
+ "name" : "self"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 15, 14, 15, 14 ],
+ "name" : "x"
+ }
+ } ],
+ "value" : {
+ "kind" : "Identifier",
+ "location" : [ 15, 18, 15, 20 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "val"
+ }
+ } ]
+ } ]
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 17, 1, 17, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 17, 1, 17, 3 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 17, 1, 17, 1 ],
+ "name" : "a"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 17, 3, 17, 3 ],
+ "className" : "A"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 17, 7, 17, 10 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 18, 1, 18, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 18, 1, 18, 3 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 18, 1, 18, 1 ],
+ "name" : "b"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 18, 3, 18, 3 ],
+ "className" : "B"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 18, 7, 18, 10 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 19, 1, 19, 10 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 19, 1, 19, 3 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 19, 1, 19, 1 ],
+ "name" : "c"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 19, 3, 19, 3 ],
+ "className" : "C"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 19, 7, 19, 10 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 21, 1, 21, 7 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 21, 1, 21, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "A"
+ },
+ "name" : "a"
+ } ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 21, 5, 21, 7 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "A"
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 21, 5, 21, 5 ],
+ "name" : "A"
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 22, 1, 22, 7 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 22, 1, 22, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "B"
+ },
+ "name" : "b"
+ } ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 22, 5, 22, 7 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "B"
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 22, 5, 22, 5 ],
+ "name" : "B"
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 23, 1, 23, 7 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 23, 1, 23, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "C"
+ },
+ "name" : "c"
+ } ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 23, 5, 23, 7 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "C"
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 23, 5, 23, 5 ],
+ "name" : "C"
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 25, 1, 25, 15 ],
+ "targets" : [ {
+ "kind" : "MemberExpr",
+ "location" : [ 25, 1, 25, 3 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 25, 1, 25, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "B"
+ },
+ "name" : "b"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 25, 3, 25, 3 ],
+ "name" : "x"
+ }
+ } ],
+ "value" : {
+ "kind" : "MethodCallExpr",
+ "location" : [ 25, 7, 25, 15 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "method" : {
+ "kind" : "MemberExpr",
+ "location" : [ 25, 7, 25, 13 ],
+ "inferredType" : {
+ "kind" : "FuncType",
+ "parameters" : [ {
+ "kind" : "ClassValueType",
+ "className" : "A"
+ } ],
+ "returnType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 25, 7, 25, 7 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "A"
+ },
+ "name" : "a"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 25, 9, 25, 13 ],
+ "name" : "get_A"
+ }
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 26, 1, 26, 15 ],
+ "targets" : [ {
+ "kind" : "MemberExpr",
+ "location" : [ 26, 1, 26, 3 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 26, 1, 26, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "A"
+ },
+ "name" : "a"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 26, 3, 26, 3 ],
+ "name" : "x"
+ }
+ } ],
+ "value" : {
+ "kind" : "MethodCallExpr",
+ "location" : [ 26, 7, 26, 15 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "method" : {
+ "kind" : "MemberExpr",
+ "location" : [ 26, 7, 26, 13 ],
+ "inferredType" : {
+ "kind" : "FuncType",
+ "parameters" : [ {
+ "kind" : "ClassValueType",
+ "className" : "A"
+ } ],
+ "returnType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 26, 7, 26, 7 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "B"
+ },
+ "name" : "b"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 26, 9, 26, 13 ],
+ "name" : "get_A"
+ }
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 27, 1, 27, 10 ],
+ "expr" : {
+ "kind" : "MethodCallExpr",
+ "location" : [ 27, 1, 27, 10 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ },
+ "method" : {
+ "kind" : "MemberExpr",
+ "location" : [ 27, 1, 27, 7 ],
+ "inferredType" : {
+ "kind" : "FuncType",
+ "parameters" : [ {
+ "kind" : "ClassValueType",
+ "className" : "C"
+ }, {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ } ],
+ "returnType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ }
+ },
+ "object" : {
+ "kind" : "Identifier",
+ "location" : [ 27, 1, 27, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "C"
+ },
+ "name" : "c"
+ },
+ "member" : {
+ "kind" : "Identifier",
+ "location" : [ 27, 3, 27, 7 ],
+ "name" : "set_A"
+ }
+ },
+ "args" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 27, 9, 27, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 0
+ } ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/decl_global_forward.py b/src/test/data/pa2/sample/decl_global_forward.py
new file mode 100644
index 0000000..b364535
--- /dev/null
+++ b/src/test/data/pa2/sample/decl_global_forward.py
@@ -0,0 +1,9 @@
+def set_x() -> int:
+ global x
+ x = 1
+ return x
+
+x:int = 0
+
+set_x()
+print(x)
diff --git a/src/test/data/pa2/sample/decl_global_forward.py.ast b/src/test/data/pa2/sample/decl_global_forward.py.ast
new file mode 100644
index 0000000..a450fe6
--- /dev/null
+++ b/src/test/data/pa2/sample/decl_global_forward.py.ast
@@ -0,0 +1,108 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 9, 9 ],
+ "declarations" : [ {
+ "kind" : "FuncDef",
+ "location" : [ 1, 1, 4, 13 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 5, 1, 9 ],
+ "name" : "set_x"
+ },
+ "params" : [ ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 16, 1, 18 ],
+ "className" : "int"
+ },
+ "declarations" : [ {
+ "kind" : "GlobalDecl",
+ "location" : [ 2, 5, 2, 12 ],
+ "variable" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 12, 2, 12 ],
+ "name" : "x"
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 3, 5, 3, 9 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 3, 5, 3, 5 ],
+ "name" : "x"
+ } ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 3, 9, 3, 9 ],
+ "value" : 1
+ }
+ }, {
+ "kind" : "ReturnStmt",
+ "location" : [ 4, 5, 4, 12 ],
+ "value" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 12, 4, 12 ],
+ "name" : "x"
+ }
+ } ]
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 6, 1, 6, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 6, 1, 6, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 6, 1, 6, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 6, 3, 6, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 9, 6, 9 ],
+ "value" : 0
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 8, 1, 8, 7 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 8, 1, 8, 7 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 1, 8, 5 ],
+ "name" : "set_x"
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 9, 1, 9, 8 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 9, 1, 9, 8 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 1, 9, 5 ],
+ "name" : "print"
+ },
+ "args" : [ {
+ "kind" : "Identifier",
+ "location" : [ 9, 7, 9, 7 ],
+ "name" : "x"
+ } ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/decl_global_forward.py.ast.typed b/src/test/data/pa2/sample/decl_global_forward.py.ast.typed
new file mode 100644
index 0000000..4d32ce7
--- /dev/null
+++ b/src/test/data/pa2/sample/decl_global_forward.py.ast.typed
@@ -0,0 +1,155 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 9, 9 ],
+ "declarations" : [ {
+ "kind" : "FuncDef",
+ "location" : [ 1, 1, 4, 13 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 5, 1, 9 ],
+ "name" : "set_x"
+ },
+ "params" : [ ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 16, 1, 18 ],
+ "className" : "int"
+ },
+ "declarations" : [ {
+ "kind" : "GlobalDecl",
+ "location" : [ 2, 5, 2, 12 ],
+ "variable" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 12, 2, 12 ],
+ "name" : "x"
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 3, 5, 3, 9 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 3, 5, 3, 5 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "x"
+ } ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 3, 9, 3, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ }, {
+ "kind" : "ReturnStmt",
+ "location" : [ 4, 5, 4, 12 ],
+ "value" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 12, 4, 12 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "x"
+ }
+ } ]
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 6, 1, 6, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 6, 1, 6, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 6, 1, 6, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 6, 3, 6, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 9, 6, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 0
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 8, 1, 8, 7 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 8, 1, 8, 7 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 1, 8, 5 ],
+ "inferredType" : {
+ "kind" : "FuncType",
+ "parameters" : [ ],
+ "returnType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "name" : "set_x"
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 9, 1, 9, 8 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 9, 1, 9, 8 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 1, 9, 5 ],
+ "inferredType" : {
+ "kind" : "FuncType",
+ "parameters" : [ {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ } ],
+ "returnType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ },
+ "name" : "print"
+ },
+ "args" : [ {
+ "kind" : "Identifier",
+ "location" : [ 9, 7, 9, 7 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "x"
+ } ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/decl_nonlocal_forward.py b/src/test/data/pa2/sample/decl_nonlocal_forward.py
new file mode 100644
index 0000000..b1ff307
--- /dev/null
+++ b/src/test/data/pa2/sample/decl_nonlocal_forward.py
@@ -0,0 +1,10 @@
+def outer() -> int:
+ def inner() -> int:
+ nonlocal x
+ x = 1
+ return x
+ x:int = 0
+ inner()
+ return x
+
+print(outer())
diff --git a/src/test/data/pa2/sample/decl_nonlocal_forward.py.ast b/src/test/data/pa2/sample/decl_nonlocal_forward.py.ast
new file mode 100644
index 0000000..1b5f11b
--- /dev/null
+++ b/src/test/data/pa2/sample/decl_nonlocal_forward.py.ast
@@ -0,0 +1,137 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 10, 15 ],
+ "declarations" : [ {
+ "kind" : "FuncDef",
+ "location" : [ 1, 1, 8, 13 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 5, 1, 9 ],
+ "name" : "outer"
+ },
+ "params" : [ ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 16, 1, 18 ],
+ "className" : "int"
+ },
+ "declarations" : [ {
+ "kind" : "FuncDef",
+ "location" : [ 2, 5, 5, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 9, 2, 13 ],
+ "name" : "inner"
+ },
+ "params" : [ ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 20, 2, 22 ],
+ "className" : "int"
+ },
+ "declarations" : [ {
+ "kind" : "NonLocalDecl",
+ "location" : [ 3, 9, 3, 18 ],
+ "variable" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 18, 3, 18 ],
+ "name" : "x"
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 4, 9, 4, 13 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 4, 9, 4, 9 ],
+ "name" : "x"
+ } ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 4, 13, 4, 13 ],
+ "value" : 1
+ }
+ }, {
+ "kind" : "ReturnStmt",
+ "location" : [ 5, 9, 5, 16 ],
+ "value" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 16, 5, 16 ],
+ "name" : "x"
+ }
+ } ]
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 6, 5, 6, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 6, 5, 6, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 6, 5, 6, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 6, 7, 6, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 13, 6, 13 ],
+ "value" : 0
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 7, 5, 7, 11 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 7, 5, 7, 11 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 5, 7, 9 ],
+ "name" : "inner"
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "ReturnStmt",
+ "location" : [ 8, 5, 8, 12 ],
+ "value" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 12, 8, 12 ],
+ "name" : "x"
+ }
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 10, 1, 10, 14 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 10, 1, 10, 14 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 10, 1, 10, 5 ],
+ "name" : "print"
+ },
+ "args" : [ {
+ "kind" : "CallExpr",
+ "location" : [ 10, 7, 10, 13 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 10, 7, 10, 11 ],
+ "name" : "outer"
+ },
+ "args" : [ ]
+ } ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/decl_nonlocal_forward.py.ast.typed b/src/test/data/pa2/sample/decl_nonlocal_forward.py.ast.typed
new file mode 100644
index 0000000..f5781a7
--- /dev/null
+++ b/src/test/data/pa2/sample/decl_nonlocal_forward.py.ast.typed
@@ -0,0 +1,196 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 10, 15 ],
+ "declarations" : [ {
+ "kind" : "FuncDef",
+ "location" : [ 1, 1, 8, 13 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 5, 1, 9 ],
+ "name" : "outer"
+ },
+ "params" : [ ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 16, 1, 18 ],
+ "className" : "int"
+ },
+ "declarations" : [ {
+ "kind" : "FuncDef",
+ "location" : [ 2, 5, 5, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 9, 2, 13 ],
+ "name" : "inner"
+ },
+ "params" : [ ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 20, 2, 22 ],
+ "className" : "int"
+ },
+ "declarations" : [ {
+ "kind" : "NonLocalDecl",
+ "location" : [ 3, 9, 3, 18 ],
+ "variable" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 18, 3, 18 ],
+ "name" : "x"
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 4, 9, 4, 13 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 4, 9, 4, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "x"
+ } ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 4, 13, 4, 13 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ }, {
+ "kind" : "ReturnStmt",
+ "location" : [ 5, 9, 5, 16 ],
+ "value" : {
+ "kind" : "Identifier",
+ "location" : [ 5, 16, 5, 16 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "x"
+ }
+ } ]
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 6, 5, 6, 13 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 6, 5, 6, 9 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 6, 5, 6, 5 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 6, 7, 6, 9 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 13, 6, 13 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 0
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 7, 5, 7, 11 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 7, 5, 7, 11 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 5, 7, 9 ],
+ "inferredType" : {
+ "kind" : "FuncType",
+ "parameters" : [ ],
+ "returnType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "name" : "inner"
+ },
+ "args" : [ ]
+ }
+ }, {
+ "kind" : "ReturnStmt",
+ "location" : [ 8, 5, 8, 12 ],
+ "value" : {
+ "kind" : "Identifier",
+ "location" : [ 8, 12, 8, 12 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "x"
+ }
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 10, 1, 10, 14 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 10, 1, 10, 14 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 10, 1, 10, 5 ],
+ "inferredType" : {
+ "kind" : "FuncType",
+ "parameters" : [ {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ } ],
+ "returnType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ },
+ "name" : "print"
+ },
+ "args" : [ {
+ "kind" : "CallExpr",
+ "location" : [ 10, 7, 10, 13 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 10, 7, 10, 11 ],
+ "inferredType" : {
+ "kind" : "FuncType",
+ "parameters" : [ ],
+ "returnType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "name" : "outer"
+ },
+ "args" : [ ]
+ } ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/expr_binary.py b/src/test/data/pa2/sample/expr_binary.py
new file mode 100644
index 0000000..b35b22d
--- /dev/null
+++ b/src/test/data/pa2/sample/expr_binary.py
@@ -0,0 +1,2 @@
+1 + 2 * 3 > 13 // 3 % 2 or 1 != 1 and False == False
+
diff --git a/src/test/data/pa2/sample/expr_binary.py.ast b/src/test/data/pa2/sample/expr_binary.py.ast
new file mode 100644
index 0000000..3e59d31
--- /dev/null
+++ b/src/test/data/pa2/sample/expr_binary.py.ast
@@ -0,0 +1,109 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 1, 53 ],
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 1, 1, 1, 52 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 1, 1, 1, 52 ],
+ "left" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 1, 1, 1, 23 ],
+ "left" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 1, 1, 1, 9 ],
+ "left" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 1, 1, 1 ],
+ "value" : 1
+ },
+ "operator" : "+",
+ "right" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 1, 5, 1, 9 ],
+ "left" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 5, 1, 5 ],
+ "value" : 2
+ },
+ "operator" : "*",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 9, 1, 9 ],
+ "value" : 3
+ }
+ }
+ },
+ "operator" : ">",
+ "right" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 1, 13, 1, 23 ],
+ "left" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 1, 13, 1, 19 ],
+ "left" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 13, 1, 14 ],
+ "value" : 13
+ },
+ "operator" : "//",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 19, 1, 19 ],
+ "value" : 3
+ }
+ },
+ "operator" : "%",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 23, 1, 23 ],
+ "value" : 2
+ }
+ }
+ },
+ "operator" : "or",
+ "right" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 1, 28, 1, 52 ],
+ "left" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 1, 28, 1, 33 ],
+ "left" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 28, 1, 28 ],
+ "value" : 1
+ },
+ "operator" : "!=",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 33, 1, 33 ],
+ "value" : 1
+ }
+ },
+ "operator" : "and",
+ "right" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 1, 39, 1, 52 ],
+ "left" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 1, 39, 1, 43 ],
+ "value" : false
+ },
+ "operator" : "==",
+ "right" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 1, 48, 1, 52 ],
+ "value" : false
+ }
+ }
+ }
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/expr_binary.py.ast.typed b/src/test/data/pa2/sample/expr_binary.py.ast.typed
new file mode 100644
index 0000000..146d277
--- /dev/null
+++ b/src/test/data/pa2/sample/expr_binary.py.ast.typed
@@ -0,0 +1,185 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 1, 53 ],
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 1, 1, 1, 52 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 1, 1, 1, 52 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "left" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 1, 1, 1, 23 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "left" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 1, 1, 1, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "left" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 1, 1, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ },
+ "operator" : "+",
+ "right" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 1, 5, 1, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "left" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 5, 1, 5 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 2
+ },
+ "operator" : "*",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 9, 1, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 3
+ }
+ }
+ },
+ "operator" : ">",
+ "right" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 1, 13, 1, 23 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "left" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 1, 13, 1, 19 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "left" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 13, 1, 14 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 13
+ },
+ "operator" : "//",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 19, 1, 19 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 3
+ }
+ },
+ "operator" : "%",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 23, 1, 23 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 2
+ }
+ }
+ },
+ "operator" : "or",
+ "right" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 1, 28, 1, 52 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "left" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 1, 28, 1, 33 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "left" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 28, 1, 28 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ },
+ "operator" : "!=",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 33, 1, 33 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ },
+ "operator" : "and",
+ "right" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 1, 39, 1, 52 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "left" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 1, 39, 1, 43 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : false
+ },
+ "operator" : "==",
+ "right" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 1, 48, 1, 52 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : false
+ }
+ }
+ }
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/expr_concat.py b/src/test/data/pa2/sample/expr_concat.py
new file mode 100644
index 0000000..68c41a0
--- /dev/null
+++ b/src/test/data/pa2/sample/expr_concat.py
@@ -0,0 +1,3 @@
+[1, 2] + [3, 4]
+"Hello " + "World"
+[1, 2] + [True]
diff --git a/src/test/data/pa2/sample/expr_concat.py.ast b/src/test/data/pa2/sample/expr_concat.py.ast
new file mode 100644
index 0000000..064862b
--- /dev/null
+++ b/src/test/data/pa2/sample/expr_concat.py.ast
@@ -0,0 +1,93 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 3, 16 ],
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 1, 1, 1, 15 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 1, 1, 1, 15 ],
+ "left" : {
+ "kind" : "ListExpr",
+ "location" : [ 1, 1, 1, 6 ],
+ "elements" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 2, 1, 2 ],
+ "value" : 1
+ }, {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 5, 1, 5 ],
+ "value" : 2
+ } ]
+ },
+ "operator" : "+",
+ "right" : {
+ "kind" : "ListExpr",
+ "location" : [ 1, 10, 1, 15 ],
+ "elements" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 11, 1, 11 ],
+ "value" : 3
+ }, {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 14, 1, 14 ],
+ "value" : 4
+ } ]
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 2, 1, 2, 18 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 2, 1, 2, 18 ],
+ "left" : {
+ "kind" : "StringLiteral",
+ "location" : [ 2, 1, 2, 8 ],
+ "value" : "Hello "
+ },
+ "operator" : "+",
+ "right" : {
+ "kind" : "StringLiteral",
+ "location" : [ 2, 12, 2, 18 ],
+ "value" : "World"
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 3, 1, 3, 15 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 3, 1, 3, 15 ],
+ "left" : {
+ "kind" : "ListExpr",
+ "location" : [ 3, 1, 3, 6 ],
+ "elements" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 3, 2, 3, 2 ],
+ "value" : 1
+ }, {
+ "kind" : "IntegerLiteral",
+ "location" : [ 3, 5, 3, 5 ],
+ "value" : 2
+ } ]
+ },
+ "operator" : "+",
+ "right" : {
+ "kind" : "ListExpr",
+ "location" : [ 3, 10, 3, 15 ],
+ "elements" : [ {
+ "kind" : "BooleanLiteral",
+ "location" : [ 3, 11, 3, 14 ],
+ "value" : true
+ } ]
+ }
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/expr_concat.py.ast.typed b/src/test/data/pa2/sample/expr_concat.py.ast.typed
new file mode 100644
index 0000000..4c61b0e
--- /dev/null
+++ b/src/test/data/pa2/sample/expr_concat.py.ast.typed
@@ -0,0 +1,175 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 3, 16 ],
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 1, 1, 1, 15 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 1, 1, 1, 15 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "left" : {
+ "kind" : "ListExpr",
+ "location" : [ 1, 1, 1, 6 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "elements" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 2, 1, 2 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }, {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 5, 1, 5 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 2
+ } ]
+ },
+ "operator" : "+",
+ "right" : {
+ "kind" : "ListExpr",
+ "location" : [ 1, 10, 1, 15 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "elements" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 11, 1, 11 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 3
+ }, {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 14, 1, 14 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 4
+ } ]
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 2, 1, 2, 18 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 2, 1, 2, 18 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "left" : {
+ "kind" : "StringLiteral",
+ "location" : [ 2, 1, 2, 8 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "value" : "Hello "
+ },
+ "operator" : "+",
+ "right" : {
+ "kind" : "StringLiteral",
+ "location" : [ 2, 12, 2, 18 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "value" : "World"
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 3, 1, 3, 15 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 3, 1, 3, 15 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ }
+ },
+ "left" : {
+ "kind" : "ListExpr",
+ "location" : [ 3, 1, 3, 6 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "elements" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 3, 2, 3, 2 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }, {
+ "kind" : "IntegerLiteral",
+ "location" : [ 3, 5, 3, 5 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 2
+ } ]
+ },
+ "operator" : "+",
+ "right" : {
+ "kind" : "ListExpr",
+ "location" : [ 3, 10, 3, 15 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ }
+ },
+ "elements" : [ {
+ "kind" : "BooleanLiteral",
+ "location" : [ 3, 11, 3, 14 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : true
+ } ]
+ }
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/expr_id.py b/src/test/data/pa2/sample/expr_id.py
new file mode 100644
index 0000000..c6fcd80
--- /dev/null
+++ b/src/test/data/pa2/sample/expr_id.py
@@ -0,0 +1,3 @@
+x:int = 1
+
+x - 1
diff --git a/src/test/data/pa2/sample/expr_id.py.ast b/src/test/data/pa2/sample/expr_id.py.ast
new file mode 100644
index 0000000..0f6ab04
--- /dev/null
+++ b/src/test/data/pa2/sample/expr_id.py.ast
@@ -0,0 +1,51 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 3, 6 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 3, 1, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 9, 1, 9 ],
+ "value" : 1
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 3, 1, 3, 5 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 3, 1, 3, 5 ],
+ "left" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 1, 3, 1 ],
+ "name" : "x"
+ },
+ "operator" : "-",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 3, 5, 3, 5 ],
+ "value" : 1
+ }
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/expr_id.py.ast.typed b/src/test/data/pa2/sample/expr_id.py.ast.typed
new file mode 100644
index 0000000..cdefa39
--- /dev/null
+++ b/src/test/data/pa2/sample/expr_id.py.ast.typed
@@ -0,0 +1,67 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 3, 6 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 3, 1, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 9, 1, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 3, 1, 3, 5 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 3, 1, 3, 5 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "left" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 1, 3, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "x"
+ },
+ "operator" : "-",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 3, 5, 3, 5 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/expr_if.py b/src/test/data/pa2/sample/expr_if.py
new file mode 100644
index 0000000..e9e9c26
--- /dev/null
+++ b/src/test/data/pa2/sample/expr_if.py
@@ -0,0 +1 @@
+3 if 1 > 2 else 4
diff --git a/src/test/data/pa2/sample/expr_if.py.ast b/src/test/data/pa2/sample/expr_if.py.ast
new file mode 100644
index 0000000..0ed9a55
--- /dev/null
+++ b/src/test/data/pa2/sample/expr_if.py.ast
@@ -0,0 +1,43 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 1, 18 ],
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 1, 1, 1, 17 ],
+ "expr" : {
+ "kind" : "IfExpr",
+ "location" : [ 1, 1, 1, 17 ],
+ "condition" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 1, 6, 1, 10 ],
+ "left" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 6, 1, 6 ],
+ "value" : 1
+ },
+ "operator" : ">",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 10, 1, 10 ],
+ "value" : 2
+ }
+ },
+ "thenExpr" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 1, 1, 1 ],
+ "value" : 3
+ },
+ "elseExpr" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 17, 1, 17 ],
+ "value" : 4
+ }
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/expr_if.py.ast.typed b/src/test/data/pa2/sample/expr_if.py.ast.typed
new file mode 100644
index 0000000..3aa7a5f
--- /dev/null
+++ b/src/test/data/pa2/sample/expr_if.py.ast.typed
@@ -0,0 +1,67 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 1, 18 ],
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 1, 1, 1, 17 ],
+ "expr" : {
+ "kind" : "IfExpr",
+ "location" : [ 1, 1, 1, 17 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "condition" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 1, 6, 1, 10 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "left" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 6, 1, 6 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ },
+ "operator" : ">",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 10, 1, 10 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 2
+ }
+ },
+ "thenExpr" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 1, 1, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 3
+ },
+ "elseExpr" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 17, 1, 17 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 4
+ }
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/expr_int.py b/src/test/data/pa2/sample/expr_int.py
new file mode 100644
index 0000000..f39d689
--- /dev/null
+++ b/src/test/data/pa2/sample/expr_int.py
@@ -0,0 +1 @@
+6 * 9
diff --git a/src/test/data/pa2/sample/expr_int.py.ast b/src/test/data/pa2/sample/expr_int.py.ast
new file mode 100644
index 0000000..2eb3e50
--- /dev/null
+++ b/src/test/data/pa2/sample/expr_int.py.ast
@@ -0,0 +1,29 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 1, 6 ],
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 1, 1, 1, 5 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 1, 1, 1, 5 ],
+ "left" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 1, 1, 1 ],
+ "value" : 6
+ },
+ "operator" : "*",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 5, 1, 5 ],
+ "value" : 9
+ }
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/expr_int.py.ast.typed b/src/test/data/pa2/sample/expr_int.py.ast.typed
new file mode 100644
index 0000000..55a6721
--- /dev/null
+++ b/src/test/data/pa2/sample/expr_int.py.ast.typed
@@ -0,0 +1,41 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 1, 6 ],
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 1, 1, 1, 5 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 1, 1, 1, 5 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "left" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 1, 1, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 6
+ },
+ "operator" : "*",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 5, 1, 5 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 9
+ }
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/expr_list_index.py b/src/test/data/pa2/sample/expr_list_index.py
new file mode 100644
index 0000000..b9d97e3
--- /dev/null
+++ b/src/test/data/pa2/sample/expr_list_index.py
@@ -0,0 +1,12 @@
+x:[int] = None
+y:int = 0
+z:[bool] = None
+o:object = None
+
+x = [1, 2, 3]
+z = [False, True]
+
+y = x[0]
+x[0] = 1
+z[1] = z[0]
+o = x[1]
diff --git a/src/test/data/pa2/sample/expr_list_index.py.ast b/src/test/data/pa2/sample/expr_list_index.py.ast
new file mode 100644
index 0000000..5cb5c50
--- /dev/null
+++ b/src/test/data/pa2/sample/expr_list_index.py.ast
@@ -0,0 +1,247 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 12, 9 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 14 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 7 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ListType",
+ "location" : [ 1, 3, 1, 7 ],
+ "elementType" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 4, 1, 6 ],
+ "className" : "int"
+ }
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 1, 11, 1, 14 ]
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 2, 1, 2, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 1, 2, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 1, 2, 1 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 3, 2, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 9, 2, 9 ],
+ "value" : 0
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 3, 1, 3, 15 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 3, 1, 3, 8 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 1, 3, 1 ],
+ "name" : "z"
+ },
+ "type" : {
+ "kind" : "ListType",
+ "location" : [ 3, 3, 3, 8 ],
+ "elementType" : {
+ "kind" : "ClassType",
+ "location" : [ 3, 4, 3, 7 ],
+ "className" : "bool"
+ }
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 3, 12, 3, 15 ]
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 4, 1, 4, 15 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 4, 1, 4, 8 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 1, 4, 1 ],
+ "name" : "o"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 3, 4, 8 ],
+ "className" : "object"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 4, 12, 4, 15 ]
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 6, 1, 6, 13 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 6, 1, 6, 1 ],
+ "name" : "x"
+ } ],
+ "value" : {
+ "kind" : "ListExpr",
+ "location" : [ 6, 5, 6, 13 ],
+ "elements" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 6, 6, 6 ],
+ "value" : 1
+ }, {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 9, 6, 9 ],
+ "value" : 2
+ }, {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 12, 6, 12 ],
+ "value" : 3
+ } ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 7, 1, 7, 17 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 7, 1, 7, 1 ],
+ "name" : "z"
+ } ],
+ "value" : {
+ "kind" : "ListExpr",
+ "location" : [ 7, 5, 7, 17 ],
+ "elements" : [ {
+ "kind" : "BooleanLiteral",
+ "location" : [ 7, 6, 7, 10 ],
+ "value" : false
+ }, {
+ "kind" : "BooleanLiteral",
+ "location" : [ 7, 13, 7, 16 ],
+ "value" : true
+ } ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 9, 1, 9, 8 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 9, 1, 9, 1 ],
+ "name" : "y"
+ } ],
+ "value" : {
+ "kind" : "IndexExpr",
+ "location" : [ 9, 5, 9, 8 ],
+ "list" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 5, 9, 5 ],
+ "name" : "x"
+ },
+ "index" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 9, 7, 9, 7 ],
+ "value" : 0
+ }
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 10, 1, 10, 8 ],
+ "targets" : [ {
+ "kind" : "IndexExpr",
+ "location" : [ 10, 1, 10, 4 ],
+ "list" : {
+ "kind" : "Identifier",
+ "location" : [ 10, 1, 10, 1 ],
+ "name" : "x"
+ },
+ "index" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 10, 3, 10, 3 ],
+ "value" : 0
+ }
+ } ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 10, 8, 10, 8 ],
+ "value" : 1
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 11, 1, 11, 11 ],
+ "targets" : [ {
+ "kind" : "IndexExpr",
+ "location" : [ 11, 1, 11, 4 ],
+ "list" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 1, 11, 1 ],
+ "name" : "z"
+ },
+ "index" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 11, 3, 11, 3 ],
+ "value" : 1
+ }
+ } ],
+ "value" : {
+ "kind" : "IndexExpr",
+ "location" : [ 11, 8, 11, 11 ],
+ "list" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 8, 11, 8 ],
+ "name" : "z"
+ },
+ "index" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 11, 10, 11, 10 ],
+ "value" : 0
+ }
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 12, 1, 12, 8 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 12, 1, 12, 1 ],
+ "name" : "o"
+ } ],
+ "value" : {
+ "kind" : "IndexExpr",
+ "location" : [ 12, 5, 12, 8 ],
+ "list" : {
+ "kind" : "Identifier",
+ "location" : [ 12, 5, 12, 5 ],
+ "name" : "x"
+ },
+ "index" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 12, 7, 12, 7 ],
+ "value" : 1
+ }
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/expr_list_index.py.ast.typed b/src/test/data/pa2/sample/expr_list_index.py.ast.typed
new file mode 100644
index 0000000..28fbe48
--- /dev/null
+++ b/src/test/data/pa2/sample/expr_list_index.py.ast.typed
@@ -0,0 +1,398 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 12, 9 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 14 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 7 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ListType",
+ "location" : [ 1, 3, 1, 7 ],
+ "elementType" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 4, 1, 6 ],
+ "className" : "int"
+ }
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 1, 11, 1, 14 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 2, 1, 2, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 1, 2, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 1, 2, 1 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 3, 2, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 2, 9, 2, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 0
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 3, 1, 3, 15 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 3, 1, 3, 8 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 1, 3, 1 ],
+ "name" : "z"
+ },
+ "type" : {
+ "kind" : "ListType",
+ "location" : [ 3, 3, 3, 8 ],
+ "elementType" : {
+ "kind" : "ClassType",
+ "location" : [ 3, 4, 3, 7 ],
+ "className" : "bool"
+ }
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 3, 12, 3, 15 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 4, 1, 4, 15 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 4, 1, 4, 8 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 1, 4, 1 ],
+ "name" : "o"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 3, 4, 8 ],
+ "className" : "object"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 4, 12, 4, 15 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 6, 1, 6, 13 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 6, 1, 6, 1 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "name" : "x"
+ } ],
+ "value" : {
+ "kind" : "ListExpr",
+ "location" : [ 6, 5, 6, 13 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "elements" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 6, 6, 6 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }, {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 9, 6, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 2
+ }, {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 12, 6, 12 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 3
+ } ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 7, 1, 7, 17 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 7, 1, 7, 1 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ }
+ },
+ "name" : "z"
+ } ],
+ "value" : {
+ "kind" : "ListExpr",
+ "location" : [ 7, 5, 7, 17 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ }
+ },
+ "elements" : [ {
+ "kind" : "BooleanLiteral",
+ "location" : [ 7, 6, 7, 10 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : false
+ }, {
+ "kind" : "BooleanLiteral",
+ "location" : [ 7, 13, 7, 16 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : true
+ } ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 9, 1, 9, 8 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 9, 1, 9, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "y"
+ } ],
+ "value" : {
+ "kind" : "IndexExpr",
+ "location" : [ 9, 5, 9, 8 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "list" : {
+ "kind" : "Identifier",
+ "location" : [ 9, 5, 9, 5 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "name" : "x"
+ },
+ "index" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 9, 7, 9, 7 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 0
+ }
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 10, 1, 10, 8 ],
+ "targets" : [ {
+ "kind" : "IndexExpr",
+ "location" : [ 10, 1, 10, 4 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "list" : {
+ "kind" : "Identifier",
+ "location" : [ 10, 1, 10, 1 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "name" : "x"
+ },
+ "index" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 10, 3, 10, 3 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 0
+ }
+ } ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 10, 8, 10, 8 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 11, 1, 11, 11 ],
+ "targets" : [ {
+ "kind" : "IndexExpr",
+ "location" : [ 11, 1, 11, 4 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "list" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 1, 11, 1 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ }
+ },
+ "name" : "z"
+ },
+ "index" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 11, 3, 11, 3 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ } ],
+ "value" : {
+ "kind" : "IndexExpr",
+ "location" : [ 11, 8, 11, 11 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "list" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 8, 11, 8 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ }
+ },
+ "name" : "z"
+ },
+ "index" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 11, 10, 11, 10 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 0
+ }
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 12, 1, 12, 8 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 12, 1, 12, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ },
+ "name" : "o"
+ } ],
+ "value" : {
+ "kind" : "IndexExpr",
+ "location" : [ 12, 5, 12, 8 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "list" : {
+ "kind" : "Identifier",
+ "location" : [ 12, 5, 12, 5 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "name" : "x"
+ },
+ "index" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 12, 7, 12, 7 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/expr_lists.py b/src/test/data/pa2/sample/expr_lists.py
new file mode 100644
index 0000000..2268a54
--- /dev/null
+++ b/src/test/data/pa2/sample/expr_lists.py
@@ -0,0 +1,12 @@
+x:[int] = None
+y:[object] = None
+z:[bool] = None
+o:object = None
+
+x = [1, 2, 3]
+x = []
+y = [1, True]
+z = [False, True]
+x = None
+o = x
+o = x = [1]
diff --git a/src/test/data/pa2/sample/expr_lists.py.ast b/src/test/data/pa2/sample/expr_lists.py.ast
new file mode 100644
index 0000000..5930b97
--- /dev/null
+++ b/src/test/data/pa2/sample/expr_lists.py.ast
@@ -0,0 +1,233 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 12, 12 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 14 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 7 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ListType",
+ "location" : [ 1, 3, 1, 7 ],
+ "elementType" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 4, 1, 6 ],
+ "className" : "int"
+ }
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 1, 11, 1, 14 ]
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 2, 1, 2, 17 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 1, 2, 10 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 1, 2, 1 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ListType",
+ "location" : [ 2, 3, 2, 10 ],
+ "elementType" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 4, 2, 9 ],
+ "className" : "object"
+ }
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 2, 14, 2, 17 ]
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 3, 1, 3, 15 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 3, 1, 3, 8 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 1, 3, 1 ],
+ "name" : "z"
+ },
+ "type" : {
+ "kind" : "ListType",
+ "location" : [ 3, 3, 3, 8 ],
+ "elementType" : {
+ "kind" : "ClassType",
+ "location" : [ 3, 4, 3, 7 ],
+ "className" : "bool"
+ }
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 3, 12, 3, 15 ]
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 4, 1, 4, 15 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 4, 1, 4, 8 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 1, 4, 1 ],
+ "name" : "o"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 3, 4, 8 ],
+ "className" : "object"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 4, 12, 4, 15 ]
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 6, 1, 6, 13 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 6, 1, 6, 1 ],
+ "name" : "x"
+ } ],
+ "value" : {
+ "kind" : "ListExpr",
+ "location" : [ 6, 5, 6, 13 ],
+ "elements" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 6, 6, 6 ],
+ "value" : 1
+ }, {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 9, 6, 9 ],
+ "value" : 2
+ }, {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 12, 6, 12 ],
+ "value" : 3
+ } ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 7, 1, 7, 6 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 7, 1, 7, 1 ],
+ "name" : "x"
+ } ],
+ "value" : {
+ "kind" : "ListExpr",
+ "location" : [ 7, 5, 7, 6 ],
+ "elements" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 8, 1, 8, 13 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 8, 1, 8, 1 ],
+ "name" : "y"
+ } ],
+ "value" : {
+ "kind" : "ListExpr",
+ "location" : [ 8, 5, 8, 13 ],
+ "elements" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 8, 6, 8, 6 ],
+ "value" : 1
+ }, {
+ "kind" : "BooleanLiteral",
+ "location" : [ 8, 9, 8, 12 ],
+ "value" : true
+ } ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 9, 1, 9, 17 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 9, 1, 9, 1 ],
+ "name" : "z"
+ } ],
+ "value" : {
+ "kind" : "ListExpr",
+ "location" : [ 9, 5, 9, 17 ],
+ "elements" : [ {
+ "kind" : "BooleanLiteral",
+ "location" : [ 9, 6, 9, 10 ],
+ "value" : false
+ }, {
+ "kind" : "BooleanLiteral",
+ "location" : [ 9, 13, 9, 16 ],
+ "value" : true
+ } ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 10, 1, 10, 8 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 10, 1, 10, 1 ],
+ "name" : "x"
+ } ],
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 10, 5, 10, 8 ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 11, 1, 11, 5 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 11, 1, 11, 1 ],
+ "name" : "o"
+ } ],
+ "value" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 5, 11, 5 ],
+ "name" : "x"
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 12, 1, 12, 11 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 12, 1, 12, 1 ],
+ "name" : "o"
+ }, {
+ "kind" : "Identifier",
+ "location" : [ 12, 5, 12, 5 ],
+ "name" : "x"
+ } ],
+ "value" : {
+ "kind" : "ListExpr",
+ "location" : [ 12, 9, 12, 11 ],
+ "elements" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 12, 10, 12, 10 ],
+ "value" : 1
+ } ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/expr_lists.py.ast.typed b/src/test/data/pa2/sample/expr_lists.py.ast.typed
new file mode 100644
index 0000000..e8c37bd
--- /dev/null
+++ b/src/test/data/pa2/sample/expr_lists.py.ast.typed
@@ -0,0 +1,374 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 12, 12 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 14 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 7 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ListType",
+ "location" : [ 1, 3, 1, 7 ],
+ "elementType" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 4, 1, 6 ],
+ "className" : "int"
+ }
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 1, 11, 1, 14 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 2, 1, 2, 17 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 1, 2, 10 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 1, 2, 1 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ListType",
+ "location" : [ 2, 3, 2, 10 ],
+ "elementType" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 4, 2, 9 ],
+ "className" : "object"
+ }
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 2, 14, 2, 17 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 3, 1, 3, 15 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 3, 1, 3, 8 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 1, 3, 1 ],
+ "name" : "z"
+ },
+ "type" : {
+ "kind" : "ListType",
+ "location" : [ 3, 3, 3, 8 ],
+ "elementType" : {
+ "kind" : "ClassType",
+ "location" : [ 3, 4, 3, 7 ],
+ "className" : "bool"
+ }
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 3, 12, 3, 15 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 4, 1, 4, 15 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 4, 1, 4, 8 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 1, 4, 1 ],
+ "name" : "o"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 3, 4, 8 ],
+ "className" : "object"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 4, 12, 4, 15 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 6, 1, 6, 13 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 6, 1, 6, 1 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "name" : "x"
+ } ],
+ "value" : {
+ "kind" : "ListExpr",
+ "location" : [ 6, 5, 6, 13 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "elements" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 6, 6, 6 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }, {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 9, 6, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 2
+ }, {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 12, 6, 12 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 3
+ } ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 7, 1, 7, 6 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 7, 1, 7, 1 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "name" : "x"
+ } ],
+ "value" : {
+ "kind" : "ListExpr",
+ "location" : [ 7, 5, 7, 6 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ },
+ "elements" : [ ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 8, 1, 8, 13 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 8, 1, 8, 1 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ }
+ },
+ "name" : "y"
+ } ],
+ "value" : {
+ "kind" : "ListExpr",
+ "location" : [ 8, 5, 8, 13 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ }
+ },
+ "elements" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 8, 6, 8, 6 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }, {
+ "kind" : "BooleanLiteral",
+ "location" : [ 8, 9, 8, 12 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : true
+ } ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 9, 1, 9, 17 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 9, 1, 9, 1 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ }
+ },
+ "name" : "z"
+ } ],
+ "value" : {
+ "kind" : "ListExpr",
+ "location" : [ 9, 5, 9, 17 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ }
+ },
+ "elements" : [ {
+ "kind" : "BooleanLiteral",
+ "location" : [ 9, 6, 9, 10 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : false
+ }, {
+ "kind" : "BooleanLiteral",
+ "location" : [ 9, 13, 9, 16 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : true
+ } ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 10, 1, 10, 8 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 10, 1, 10, 1 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "name" : "x"
+ } ],
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 10, 5, 10, 8 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 11, 1, 11, 5 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 11, 1, 11, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ },
+ "name" : "o"
+ } ],
+ "value" : {
+ "kind" : "Identifier",
+ "location" : [ 11, 5, 11, 5 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "name" : "x"
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 12, 1, 12, 11 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 12, 1, 12, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ },
+ "name" : "o"
+ }, {
+ "kind" : "Identifier",
+ "location" : [ 12, 5, 12, 5 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "name" : "x"
+ } ],
+ "value" : {
+ "kind" : "ListExpr",
+ "location" : [ 12, 9, 12, 11 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "elements" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 12, 10, 12, 10 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ } ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/expr_unary.py b/src/test/data/pa2/sample/expr_unary.py
new file mode 100644
index 0000000..58d9627
--- /dev/null
+++ b/src/test/data/pa2/sample/expr_unary.py
@@ -0,0 +1,2 @@
+-1
+not False
diff --git a/src/test/data/pa2/sample/expr_unary.py.ast b/src/test/data/pa2/sample/expr_unary.py.ast
new file mode 100644
index 0000000..4f1abf3
--- /dev/null
+++ b/src/test/data/pa2/sample/expr_unary.py.ast
@@ -0,0 +1,37 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 2, 10 ],
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 1, 1, 1, 2 ],
+ "expr" : {
+ "kind" : "UnaryExpr",
+ "location" : [ 1, 1, 1, 2 ],
+ "operator" : "-",
+ "operand" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 2, 1, 2 ],
+ "value" : 1
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 2, 1, 2, 9 ],
+ "expr" : {
+ "kind" : "UnaryExpr",
+ "location" : [ 2, 1, 2, 9 ],
+ "operator" : "not",
+ "operand" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 2, 5, 2, 9 ],
+ "value" : false
+ }
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/expr_unary.py.ast.typed b/src/test/data/pa2/sample/expr_unary.py.ast.typed
new file mode 100644
index 0000000..77b0fd0
--- /dev/null
+++ b/src/test/data/pa2/sample/expr_unary.py.ast.typed
@@ -0,0 +1,53 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 2, 10 ],
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 1, 1, 1, 2 ],
+ "expr" : {
+ "kind" : "UnaryExpr",
+ "location" : [ 1, 1, 1, 2 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "operator" : "-",
+ "operand" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 2, 1, 2 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ }
+ }, {
+ "kind" : "ExprStmt",
+ "location" : [ 2, 1, 2, 9 ],
+ "expr" : {
+ "kind" : "UnaryExpr",
+ "location" : [ 2, 1, 2, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "operator" : "not",
+ "operand" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 2, 5, 2, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : false
+ }
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/expr_var_assign.py b/src/test/data/pa2/sample/expr_var_assign.py
new file mode 100644
index 0000000..3b8ebfe
--- /dev/null
+++ b/src/test/data/pa2/sample/expr_var_assign.py
@@ -0,0 +1,4 @@
+x:int = 1
+o:object = None
+
+x = o = 42
diff --git a/src/test/data/pa2/sample/expr_var_assign.py.ast b/src/test/data/pa2/sample/expr_var_assign.py.ast
new file mode 100644
index 0000000..5b8093e
--- /dev/null
+++ b/src/test/data/pa2/sample/expr_var_assign.py.ast
@@ -0,0 +1,71 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 4, 11 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 3, 1, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 9, 1, 9 ],
+ "value" : 1
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 2, 1, 2, 15 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 1, 2, 8 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 1, 2, 1 ],
+ "name" : "o"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 3, 2, 8 ],
+ "className" : "object"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 2, 12, 2, 15 ]
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 4, 1, 4, 10 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 4, 1, 4, 1 ],
+ "name" : "x"
+ }, {
+ "kind" : "Identifier",
+ "location" : [ 4, 5, 4, 5 ],
+ "name" : "o"
+ } ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 4, 9, 4, 10 ],
+ "value" : 42
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/expr_var_assign.py.ast.typed b/src/test/data/pa2/sample/expr_var_assign.py.ast.typed
new file mode 100644
index 0000000..950866b
--- /dev/null
+++ b/src/test/data/pa2/sample/expr_var_assign.py.ast.typed
@@ -0,0 +1,91 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 4, 11 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 3, 1, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 9, 1, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 2, 1, 2, 15 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 1, 2, 8 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 1, 2, 1 ],
+ "name" : "o"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 3, 2, 8 ],
+ "className" : "object"
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 2, 12, 2, 15 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 4, 1, 4, 10 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 4, 1, 4, 1 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "x"
+ }, {
+ "kind" : "Identifier",
+ "location" : [ 4, 5, 4, 5 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ },
+ "name" : "o"
+ } ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 4, 9, 4, 10 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 42
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/func_def_call.py b/src/test/data/pa2/sample/func_def_call.py
new file mode 100644
index 0000000..e5f4e8b
--- /dev/null
+++ b/src/test/data/pa2/sample/func_def_call.py
@@ -0,0 +1,7 @@
+def foo(x:str, y:bool) -> int:
+ return bar()
+
+def bar() -> int:
+ return 1
+
+foo("Hello", False)
diff --git a/src/test/data/pa2/sample/func_def_call.py.ast b/src/test/data/pa2/sample/func_def_call.py.ast
new file mode 100644
index 0000000..b6194bd
--- /dev/null
+++ b/src/test/data/pa2/sample/func_def_call.py.ast
@@ -0,0 +1,111 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 7, 20 ],
+ "declarations" : [ {
+ "kind" : "FuncDef",
+ "location" : [ 1, 1, 2, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 5, 1, 7 ],
+ "name" : "foo"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 1, 9, 1, 13 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 9 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 11, 1, 13 ],
+ "className" : "str"
+ }
+ }, {
+ "kind" : "TypedVar",
+ "location" : [ 1, 16, 1, 21 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 16, 1, 16 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 18, 1, 21 ],
+ "className" : "bool"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 27, 1, 29 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 2, 5, 2, 16 ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 2, 12, 2, 16 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 12, 2, 14 ],
+ "name" : "bar"
+ },
+ "args" : [ ]
+ }
+ } ]
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 4, 1, 5, 13 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 5, 4, 7 ],
+ "name" : "bar"
+ },
+ "params" : [ ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 14, 4, 16 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 5, 5, 5, 12 ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 5, 12, 5, 12 ],
+ "value" : 1
+ }
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 7, 1, 7, 19 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 7, 1, 7, 19 ],
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 1, 7, 3 ],
+ "name" : "foo"
+ },
+ "args" : [ {
+ "kind" : "StringLiteral",
+ "location" : [ 7, 5, 7, 11 ],
+ "value" : "Hello"
+ }, {
+ "kind" : "BooleanLiteral",
+ "location" : [ 7, 14, 7, 18 ],
+ "value" : false
+ } ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/func_def_call.py.ast.typed b/src/test/data/pa2/sample/func_def_call.py.ast.typed
new file mode 100644
index 0000000..20e0bde
--- /dev/null
+++ b/src/test/data/pa2/sample/func_def_call.py.ast.typed
@@ -0,0 +1,153 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 7, 20 ],
+ "declarations" : [ {
+ "kind" : "FuncDef",
+ "location" : [ 1, 1, 2, 17 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 5, 1, 7 ],
+ "name" : "foo"
+ },
+ "params" : [ {
+ "kind" : "TypedVar",
+ "location" : [ 1, 9, 1, 13 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 9, 1, 9 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 11, 1, 13 ],
+ "className" : "str"
+ }
+ }, {
+ "kind" : "TypedVar",
+ "location" : [ 1, 16, 1, 21 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 16, 1, 16 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 18, 1, 21 ],
+ "className" : "bool"
+ }
+ } ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 27, 1, 29 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 2, 5, 2, 16 ],
+ "value" : {
+ "kind" : "CallExpr",
+ "location" : [ 2, 12, 2, 16 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 12, 2, 14 ],
+ "inferredType" : {
+ "kind" : "FuncType",
+ "parameters" : [ ],
+ "returnType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "name" : "bar"
+ },
+ "args" : [ ]
+ }
+ } ]
+ }, {
+ "kind" : "FuncDef",
+ "location" : [ 4, 1, 5, 13 ],
+ "name" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 5, 4, 7 ],
+ "name" : "bar"
+ },
+ "params" : [ ],
+ "returnType" : {
+ "kind" : "ClassType",
+ "location" : [ 4, 14, 4, 16 ],
+ "className" : "int"
+ },
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "ReturnStmt",
+ "location" : [ 5, 5, 5, 12 ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 5, 12, 5, 12 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ } ]
+ } ],
+ "statements" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 7, 1, 7, 19 ],
+ "expr" : {
+ "kind" : "CallExpr",
+ "location" : [ 7, 1, 7, 19 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "function" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 1, 7, 3 ],
+ "inferredType" : {
+ "kind" : "FuncType",
+ "parameters" : [ {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ }, {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ } ],
+ "returnType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "name" : "foo"
+ },
+ "args" : [ {
+ "kind" : "StringLiteral",
+ "location" : [ 7, 5, 7, 11 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "value" : "Hello"
+ }, {
+ "kind" : "BooleanLiteral",
+ "location" : [ 7, 14, 7, 18 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : false
+ } ]
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/stmt_for_lists.py b/src/test/data/pa2/sample/stmt_for_lists.py
new file mode 100644
index 0000000..235fb2f
--- /dev/null
+++ b/src/test/data/pa2/sample/stmt_for_lists.py
@@ -0,0 +1,4 @@
+x:int = 0
+
+for x in [1, 2, 3]:
+ x + 1
diff --git a/src/test/data/pa2/sample/stmt_for_lists.py.ast b/src/test/data/pa2/sample/stmt_for_lists.py.ast
new file mode 100644
index 0000000..3e6fb8f
--- /dev/null
+++ b/src/test/data/pa2/sample/stmt_for_lists.py.ast
@@ -0,0 +1,77 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 5, 1 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 3, 1, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 9, 1, 9 ],
+ "value" : 0
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "ForStmt",
+ "location" : [ 3, 1, 5, 1 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 5, 3, 5 ],
+ "name" : "x"
+ },
+ "iterable" : {
+ "kind" : "ListExpr",
+ "location" : [ 3, 10, 3, 18 ],
+ "elements" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 3, 11, 3, 11 ],
+ "value" : 1
+ }, {
+ "kind" : "IntegerLiteral",
+ "location" : [ 3, 14, 3, 14 ],
+ "value" : 2
+ }, {
+ "kind" : "IntegerLiteral",
+ "location" : [ 3, 17, 3, 17 ],
+ "value" : 3
+ } ]
+ },
+ "body" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 4, 5, 4, 9 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 4, 5, 4, 9 ],
+ "left" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 5, 4, 5 ],
+ "name" : "x"
+ },
+ "operator" : "+",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 4, 9, 4, 9 ],
+ "value" : 1
+ }
+ }
+ } ]
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/stmt_for_lists.py.ast.typed b/src/test/data/pa2/sample/stmt_for_lists.py.ast.typed
new file mode 100644
index 0000000..9bd4123
--- /dev/null
+++ b/src/test/data/pa2/sample/stmt_for_lists.py.ast.typed
@@ -0,0 +1,116 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 5, 1 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 9 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 3, 1, 5 ],
+ "className" : "int"
+ }
+ },
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 1, 9, 1, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 0
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "ForStmt",
+ "location" : [ 3, 1, 5, 1 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 5, 3, 5 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "x"
+ },
+ "iterable" : {
+ "kind" : "ListExpr",
+ "location" : [ 3, 10, 3, 18 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "elements" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 3, 11, 3, 11 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }, {
+ "kind" : "IntegerLiteral",
+ "location" : [ 3, 14, 3, 14 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 2
+ }, {
+ "kind" : "IntegerLiteral",
+ "location" : [ 3, 17, 3, 17 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 3
+ } ]
+ },
+ "body" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 4, 5, 4, 9 ],
+ "expr" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 4, 5, 4, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "left" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 5, 4, 5 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "name" : "x"
+ },
+ "operator" : "+",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 4, 9, 4, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ }
+ } ]
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/stmt_for_strings.py b/src/test/data/pa2/sample/stmt_for_strings.py
new file mode 100644
index 0000000..b135f8b
--- /dev/null
+++ b/src/test/data/pa2/sample/stmt_for_strings.py
@@ -0,0 +1,4 @@
+s:str = "Hello"
+
+for s in s:
+ s[0]
diff --git a/src/test/data/pa2/sample/stmt_for_strings.py.ast b/src/test/data/pa2/sample/stmt_for_strings.py.ast
new file mode 100644
index 0000000..6e837a5
--- /dev/null
+++ b/src/test/data/pa2/sample/stmt_for_strings.py.ast
@@ -0,0 +1,64 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 5, 1 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 15 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "s"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 3, 1, 5 ],
+ "className" : "str"
+ }
+ },
+ "value" : {
+ "kind" : "StringLiteral",
+ "location" : [ 1, 9, 1, 15 ],
+ "value" : "Hello"
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "ForStmt",
+ "location" : [ 3, 1, 5, 1 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 5, 3, 5 ],
+ "name" : "s"
+ },
+ "iterable" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 10, 3, 10 ],
+ "name" : "s"
+ },
+ "body" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 4, 5, 4, 8 ],
+ "expr" : {
+ "kind" : "IndexExpr",
+ "location" : [ 4, 5, 4, 8 ],
+ "list" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 5, 4, 5 ],
+ "name" : "s"
+ },
+ "index" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 4, 7, 4, 7 ],
+ "value" : 0
+ }
+ }
+ } ]
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/stmt_for_strings.py.ast.typed b/src/test/data/pa2/sample/stmt_for_strings.py.ast.typed
new file mode 100644
index 0000000..0f36ad0
--- /dev/null
+++ b/src/test/data/pa2/sample/stmt_for_strings.py.ast.typed
@@ -0,0 +1,88 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 5, 1 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 15 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 5 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "s"
+ },
+ "type" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 3, 1, 5 ],
+ "className" : "str"
+ }
+ },
+ "value" : {
+ "kind" : "StringLiteral",
+ "location" : [ 1, 9, 1, 15 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "value" : "Hello"
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "ForStmt",
+ "location" : [ 3, 1, 5, 1 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 5, 3, 5 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "name" : "s"
+ },
+ "iterable" : {
+ "kind" : "Identifier",
+ "location" : [ 3, 10, 3, 10 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "name" : "s"
+ },
+ "body" : [ {
+ "kind" : "ExprStmt",
+ "location" : [ 4, 5, 4, 8 ],
+ "expr" : {
+ "kind" : "IndexExpr",
+ "location" : [ 4, 5, 4, 8 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "list" : {
+ "kind" : "Identifier",
+ "location" : [ 4, 5, 4, 5 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "str"
+ },
+ "name" : "s"
+ },
+ "index" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 4, 7, 4, 7 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 0
+ }
+ }
+ } ]
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/stmt_if.py b/src/test/data/pa2/sample/stmt_if.py
new file mode 100644
index 0000000..d5053bf
--- /dev/null
+++ b/src/test/data/pa2/sample/stmt_if.py
@@ -0,0 +1,7 @@
+if False:
+ pass
+elif True:
+ if 1 == 1:
+ pass
+else:
+ pass
diff --git a/src/test/data/pa2/sample/stmt_if.py.ast b/src/test/data/pa2/sample/stmt_if.py.ast
new file mode 100644
index 0000000..48c33f3
--- /dev/null
+++ b/src/test/data/pa2/sample/stmt_if.py.ast
@@ -0,0 +1,51 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 8, 1 ],
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "IfStmt",
+ "location" : [ 1, 1, 8, 1 ],
+ "condition" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 1, 4, 1, 8 ],
+ "value" : false
+ },
+ "thenBody" : [ ],
+ "elseBody" : [ {
+ "kind" : "IfStmt",
+ "location" : [ 3, 1, 8, 1 ],
+ "condition" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 3, 6, 3, 9 ],
+ "value" : true
+ },
+ "thenBody" : [ {
+ "kind" : "IfStmt",
+ "location" : [ 4, 5, 6, 0 ],
+ "condition" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 4, 8, 4, 13 ],
+ "left" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 4, 8, 4, 8 ],
+ "value" : 1
+ },
+ "operator" : "==",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 4, 13, 4, 13 ],
+ "value" : 1
+ }
+ },
+ "thenBody" : [ ],
+ "elseBody" : [ ]
+ } ],
+ "elseBody" : [ ]
+ } ]
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/stmt_if.py.ast.typed b/src/test/data/pa2/sample/stmt_if.py.ast.typed
new file mode 100644
index 0000000..3453f95
--- /dev/null
+++ b/src/test/data/pa2/sample/stmt_if.py.ast.typed
@@ -0,0 +1,71 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 8, 1 ],
+ "declarations" : [ ],
+ "statements" : [ {
+ "kind" : "IfStmt",
+ "location" : [ 1, 1, 8, 1 ],
+ "condition" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 1, 4, 1, 8 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : false
+ },
+ "thenBody" : [ ],
+ "elseBody" : [ {
+ "kind" : "IfStmt",
+ "location" : [ 3, 1, 8, 1 ],
+ "condition" : {
+ "kind" : "BooleanLiteral",
+ "location" : [ 3, 6, 3, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "value" : true
+ },
+ "thenBody" : [ {
+ "kind" : "IfStmt",
+ "location" : [ 4, 5, 6, 0 ],
+ "condition" : {
+ "kind" : "BinaryExpr",
+ "location" : [ 4, 8, 4, 13 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "bool"
+ },
+ "left" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 4, 8, 4, 8 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ },
+ "operator" : "==",
+ "right" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 4, 13, 4, 13 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }
+ },
+ "thenBody" : [ ],
+ "elseBody" : [ ]
+ } ],
+ "elseBody" : [ ]
+ } ]
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/stmt_list_assign.py b/src/test/data/pa2/sample/stmt_list_assign.py
new file mode 100644
index 0000000..34221dd
--- /dev/null
+++ b/src/test/data/pa2/sample/stmt_list_assign.py
@@ -0,0 +1,7 @@
+x:[int] = None
+y:[object] = None
+
+x = [1, 2]
+y = [None]
+x[0] = 3
+x[1] = y[0] = 4
diff --git a/src/test/data/pa2/sample/stmt_list_assign.py.ast b/src/test/data/pa2/sample/stmt_list_assign.py.ast
new file mode 100644
index 0000000..cac7d91
--- /dev/null
+++ b/src/test/data/pa2/sample/stmt_list_assign.py.ast
@@ -0,0 +1,155 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 7, 16 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 14 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 7 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ListType",
+ "location" : [ 1, 3, 1, 7 ],
+ "elementType" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 4, 1, 6 ],
+ "className" : "int"
+ }
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 1, 11, 1, 14 ]
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 2, 1, 2, 17 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 1, 2, 10 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 1, 2, 1 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ListType",
+ "location" : [ 2, 3, 2, 10 ],
+ "elementType" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 4, 2, 9 ],
+ "className" : "object"
+ }
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 2, 14, 2, 17 ]
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 4, 1, 4, 10 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 4, 1, 4, 1 ],
+ "name" : "x"
+ } ],
+ "value" : {
+ "kind" : "ListExpr",
+ "location" : [ 4, 5, 4, 10 ],
+ "elements" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 4, 6, 4, 6 ],
+ "value" : 1
+ }, {
+ "kind" : "IntegerLiteral",
+ "location" : [ 4, 9, 4, 9 ],
+ "value" : 2
+ } ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 5, 1, 5, 10 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 5, 1, 5, 1 ],
+ "name" : "y"
+ } ],
+ "value" : {
+ "kind" : "ListExpr",
+ "location" : [ 5, 5, 5, 10 ],
+ "elements" : [ {
+ "kind" : "NoneLiteral",
+ "location" : [ 5, 6, 5, 9 ]
+ } ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 6, 1, 6, 8 ],
+ "targets" : [ {
+ "kind" : "IndexExpr",
+ "location" : [ 6, 1, 6, 4 ],
+ "list" : {
+ "kind" : "Identifier",
+ "location" : [ 6, 1, 6, 1 ],
+ "name" : "x"
+ },
+ "index" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 3, 6, 3 ],
+ "value" : 0
+ }
+ } ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 6, 8, 6, 8 ],
+ "value" : 3
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 7, 1, 7, 15 ],
+ "targets" : [ {
+ "kind" : "IndexExpr",
+ "location" : [ 7, 1, 7, 4 ],
+ "list" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 1, 7, 1 ],
+ "name" : "x"
+ },
+ "index" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 7, 3, 7, 3 ],
+ "value" : 1
+ }
+ }, {
+ "kind" : "IndexExpr",
+ "location" : [ 7, 8, 7, 11 ],
+ "list" : {
+ "kind" : "Identifier",
+ "location" : [ 7, 8, 7, 8 ],
+ "name" : "y"
+ },
+ "index" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 7, 10, 7, 10 ],
+ "value" : 0
+ }
+ } ],
+ "value" : {
+ "kind" : "IntegerLiteral",
+ "location" : [ 7, 15, 7, 15 ],
+ "value" : 4
+ }
+ } ],
+ "errors" : {
+ "errors" : [ ],
+ "kind" : "Errors",
+ "location" : [ 0, 0, 0, 0 ]
+ }
+}
\ No newline at end of file
diff --git a/src/test/data/pa2/sample/stmt_list_assign.py.ast.typed b/src/test/data/pa2/sample/stmt_list_assign.py.ast.typed
new file mode 100644
index 0000000..5fefc31
--- /dev/null
+++ b/src/test/data/pa2/sample/stmt_list_assign.py.ast.typed
@@ -0,0 +1,256 @@
+{
+ "kind" : "Program",
+ "location" : [ 1, 1, 7, 16 ],
+ "declarations" : [ {
+ "kind" : "VarDef",
+ "location" : [ 1, 1, 1, 14 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 1, 1, 1, 7 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 1, 1, 1, 1 ],
+ "name" : "x"
+ },
+ "type" : {
+ "kind" : "ListType",
+ "location" : [ 1, 3, 1, 7 ],
+ "elementType" : {
+ "kind" : "ClassType",
+ "location" : [ 1, 4, 1, 6 ],
+ "className" : "int"
+ }
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 1, 11, 1, 14 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ }, {
+ "kind" : "VarDef",
+ "location" : [ 2, 1, 2, 17 ],
+ "var" : {
+ "kind" : "TypedVar",
+ "location" : [ 2, 1, 2, 10 ],
+ "identifier" : {
+ "kind" : "Identifier",
+ "location" : [ 2, 1, 2, 1 ],
+ "name" : "y"
+ },
+ "type" : {
+ "kind" : "ListType",
+ "location" : [ 2, 3, 2, 10 ],
+ "elementType" : {
+ "kind" : "ClassType",
+ "location" : [ 2, 4, 2, 9 ],
+ "className" : "object"
+ }
+ }
+ },
+ "value" : {
+ "kind" : "NoneLiteral",
+ "location" : [ 2, 14, 2, 17 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : ""
+ }
+ }
+ } ],
+ "statements" : [ {
+ "kind" : "AssignStmt",
+ "location" : [ 4, 1, 4, 10 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 4, 1, 4, 1 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "name" : "x"
+ } ],
+ "value" : {
+ "kind" : "ListExpr",
+ "location" : [ 4, 5, 4, 10 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ }
+ },
+ "elements" : [ {
+ "kind" : "IntegerLiteral",
+ "location" : [ 4, 6, 4, 6 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 1
+ }, {
+ "kind" : "IntegerLiteral",
+ "location" : [ 4, 9, 4, 9 ],
+ "inferredType" : {
+ "kind" : "ClassValueType",
+ "className" : "int"
+ },
+ "value" : 2
+ } ]
+ }
+ }, {
+ "kind" : "AssignStmt",
+ "location" : [ 5, 1, 5, 10 ],
+ "targets" : [ {
+ "kind" : "Identifier",
+ "location" : [ 5, 1, 5, 1 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "object"
+ }
+ },
+ "name" : "y"
+ } ],
+ "value" : {
+ "kind" : "ListExpr",
+ "location" : [ 5, 5, 5, 10 ],
+ "inferredType" : {
+ "kind" : "ListValueType",
+ "elementType" : {
+ "kind" : "ClassValueType",
+ "className" : "