Mercurial > projects > dang
view sema/ScopeCheck.d @ 154:0ea5d2f3e96b
Parsing "this" as constructor. Also removed regex from the test run program(seg fault - dmd???)
author | Anders Johnsen <skabet@gmail.com> |
---|---|
date | Mon, 21 Jul 2008 21:45:54 +0200 |
parents | a14ac9e5c858 |
children | 57b0b4464a0b |
line wrap: on
line source
module sema.ScopeCheck; import sema.Visitor, sema.Symbol, sema.Scope, sema.DType; import basic.Message, basic.Attribute; 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.get); if(symbol is null) messages.report(UndefinedIdentifier, i.loc) .arg(i.get); } override void visitVarDecl(VarDecl d) { if(!d.env.findType(d.varType.get)) messages.report(UndefinedType, d.varType.loc) .arg(d.varType.get); auto env = d.env; if (d.env.enclosing) if (d.env.enclosing.find(d.identifier.get) !is null) if (d.env.parentFunction !is null) while( d.env.parentFunction.env !is env) { if (d.env.enclosing.find(d.identifier.get).env == env) messages.report(CannotRedeclare, d.identifier.loc) .arg(d.identifier.get); env = env.enclosing; } visitExp(d.identifier); if (d.init) visitExp(d.init); } override void visitFuncDecl(FuncDecl f) { visitExp(f.identifier); inFunction = true; foreach (stmt; f.statements) visitStmt(stmt); inFunction = false; } 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); else internalCheckProtection(res, child); 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); else internalCheckProtection(res, child); return res; } } override void visitExp(Exp exp) { if (exp.expType == ExpType.Identifier && inFunction && exp.env.find((cast(Identifier)exp).get) !is null) { if (exp.env.findType((cast(Identifier)exp).get) is null) internalCheckProtection( exp.env.find((cast(Identifier)exp).get).sym, cast(Identifier)exp); } super.visitExp(exp); } private void internalCheckProtection(Symbol sym, Identifier iden) { if (isChildOf(sym.decl.env, iden.env)) return; switch(sym.decl.att.getProtection) { case Protection.Private: /* if (iden.env.inModule == sym.decl.getIdentifier.env.inModule && sym.decl.getIdentifier.env.enclosing == iden.env.inModule) {} else*/ messages.report(CannotAccessPrivate, iden.loc); return; default: return; } } private bool isChildOf(Scope parent, Scope child) { if (child is parent) return true; if (child.enclosing !is null) return isChildOf(parent, child.enclosing); return false; } private bool isType(char[] s) { return (s in types? true : false); } int[char[]] types; MessageHandler messages; bool inFunction; }