view sema/ScopeCheck.d @ 135:9869194de9b7

Removed some output We have 15 tests that fail in release mode and 17 in debug - both from things that are only handled by an assert. One is a comments lexing test, that fails on an invalid location in debug The other is returning a struct - it's cought in codegen by an assert, but should be checked explicitly before that
author Anders Halager <halager@gmail.com>
date Wed, 09 Jul 2008 13:38:11 +0200
parents 6545a8d59596
children 2be29b296081
line wrap: on
line source

module sema.ScopeCheck;

import sema.Visitor,
       sema.Symbol,
       sema.DType;

import basic.Message;

import tango.io.Stdout;

class ScopeCheck : Visitor!(void)
{

    this(MessageHandler messages)
    {
        this.messages = messages;
    }

    override void visitIdentifier(Identifier i)
    {
        auto symbol = i.env.find(i);

        if(symbol is null)
            messages.report(UndefinedIdentifier, i.loc)
                .arg(i.get);
    }

    override void visitVarDecl(VarDecl d)
    {
        if(!d.env.findType(d.varType))
            messages.report(UndefinedType, d.varType.loc)
                .arg(d.varType.get);

        visitExp(d.identifier);
        if (d.init)
            visitExp(d.init);
    }

    override void visitFuncDecl(FuncDecl f)
    {
        visitExp(f.identifier);

        foreach (stmt; f.statements)
            visitStmt(stmt);
    }

    override void visitImportDecl(ImportDecl) { }

    override void visitCastExp(CastExp exp)
    {
        visitExp(exp.exp);
    }

    override void visitMemberReference(MemberReference m)
    {
        internalVisitMemberRef(m);
    }

    private Symbol internalVisitMemberRef(MemberReference m)
    {
        switch(m.target.expType)
        {
            case ExpType.Identifier:
                auto target = cast(Identifier)m.target;
                auto child = m.child;
                auto st = target.getSymbol;
                auto res = st.findMember(child.get);

                if(!res)
                    messages.report(MissingMember, m.loc)
                        .arg(st.type.name)
                        .arg(target.get)
                        .arg(child.get);

                return res;
            case ExpType.MemberReference:
                Symbol s = internalVisitMemberRef(cast(MemberReference)m.target);
                if(!s)
                    return null;
                auto target = cast(Identifier)m.target;
                auto child = m.child;
                auto res = s.findMember(child.get);

                if(!res)
                    messages.report(MissingMember, m.loc)
                        .arg(s.type.name)
                        .arg(s.getFQN)
                        .arg(child.get);

                return res;
        }
    }

    private bool isType(char[] s)
    {
        return (s in types? true : false);
    }

    int[char[]] types;
    MessageHandler messages;
}