|
|
@ -163,7 +163,7 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
|
|
|
|
|
|
|
|
|
|
|
if(!firstPass){
|
|
|
|
if(!firstPass){
|
|
|
|
ValueType returnType = ValueType.annotationToValueType(node.returnType);
|
|
|
|
ValueType returnType = ValueType.annotationToValueType(node.returnType);
|
|
|
|
if(returnType!=null && !returnType.isSpecialType() && !(globals.get(returnType.className()) instanceof ClassVType))
|
|
|
|
if(returnType!=null && !returnType.isSpecialType() && !returnType.isListType() && !(globals.get(returnType.className()) instanceof ClassVType))
|
|
|
|
errors.semError(
|
|
|
|
errors.semError(
|
|
|
|
node.returnType, "Invalid type annotation; there is no class named: %s", returnType.className());
|
|
|
|
node.returnType, "Invalid type annotation; there is no class named: %s", returnType.className());
|
|
|
|
|
|
|
|
|
|
|
@ -260,7 +260,8 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
|
|
|
!(params.get(0) instanceof ClassValueType)||
|
|
|
|
!(params.get(0) instanceof ClassValueType)||
|
|
|
|
!((ClassValueType)params.get(0)).className().equals(current_class.className))
|
|
|
|
!((ClassValueType)params.get(0)).className().equals(current_class.className))
|
|
|
|
errors.semError(id, "Method overridden with different type signature: __init__");
|
|
|
|
errors.semError(id, "Method overridden with different type signature: __init__");
|
|
|
|
else sym.put(name, current_func);
|
|
|
|
else
|
|
|
|
|
|
|
|
sym.put(name, current_func);
|
|
|
|
if(params.size() < 1 || (params.get(0) instanceof ClassValueType==false) || ((ClassValueType)params.get(0)).className().equals(current_class.className)==false)
|
|
|
|
if(params.size() < 1 || (params.get(0) instanceof ClassValueType==false) || ((ClassValueType)params.get(0)).className().equals(current_class.className)==false)
|
|
|
|
errors.semError(
|
|
|
|
errors.semError(
|
|
|
|
id, "First parameter of the following method must be of the enclosing class: %s", name);
|
|
|
|
id, "First parameter of the following method must be of the enclosing class: %s", name);
|
|
|
@ -283,7 +284,10 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
sym.put(name, current_func);
|
|
|
|
sym.put(name, current_func);
|
|
|
|
} else if (super_syms.contains(name))
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (name.equals("__init__") && !(type instanceof FuncType))
|
|
|
|
|
|
|
|
errors.semError(id, "Cannot re-define attribute: %s", name);
|
|
|
|
|
|
|
|
else if (super_syms.contains(name))
|
|
|
|
errors.semError(id, "Cannot re-define attribute: %s", name);
|
|
|
|
errors.semError(id, "Cannot re-define attribute: %s", name);
|
|
|
|
else
|
|
|
|
else
|
|
|
|
sym.put(name, type);
|
|
|
|
sym.put(name, type);
|
|
|
@ -304,21 +308,17 @@ public class DeclarationAnalyzer extends AbstractNodeAnalyzer<Type>
|
|
|
|
}
|
|
|
|
}
|
|
|
|
boolean isVariableType(Type ty)
|
|
|
|
boolean isVariableType(Type ty)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return ty.isSpecialType() || ty.equals(Type.OBJECT_TYPE);
|
|
|
|
return ty.isSpecialType() || ty.equals(Type.OBJECT_TYPE)|| ty.isListType();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public Type analyze(NonLocalDecl node)
|
|
|
|
public Type analyze(NonLocalDecl node)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
SymbolTable<Type> curr_sym=sym;
|
|
|
|
SymbolTable<Type> parent=sym.getParent();
|
|
|
|
while(curr_sym.getParent()!=null)
|
|
|
|
if (parent.getParent()!=null && parent.declares(node.variable.name) && isVariableType(sym.get(node.variable.name)))
|
|
|
|
{
|
|
|
|
|
|
|
|
if (curr_sym.declares(node.variable.name) && isVariableType(sym.get(node.variable.name)))
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
sym.put(node.variable.name, sym.get(node.variable.name));
|
|
|
|
sym.put(node.variable.name, sym.get(node.variable.name));
|
|
|
|
return sym.get(node.variable.name);
|
|
|
|
return sym.get(node.variable.name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
curr_sym=curr_sym.getParent();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
errors.semError(
|
|
|
|
errors.semError(
|
|
|
|
node.variable, "Not a nonlocal variable: %s", node.variable.name);
|
|
|
|
node.variable, "Not a nonlocal variable: %s", node.variable.name);
|
|
|
|
return null;
|
|
|
|
return null;
|
|
|
|