#include "AST.h" #include "MethodDecl.h" #include "code-util.h" #include "errors.h" #include "is-main.h" MethodSet mainMethods; //////////////////////////////////////////////////////////////////////// bool MethodDeclNode::isMain() const { return decl()->isMain(); } bool MethodDecl::isMain() { if ((modifiers() & Common::Static) && (modifiers() & Common::Public) && *name() == "main") { assert( methodType()->kind() == Common::MethodKind ); return methodType()->isMain(); } else return false; } bool MethodTypeNode::isMain() const { if (returnType()->kind() == VoidKind && paramTypes()->arity() == 1) { const TypeNode ¶m = *paramTypes()->child( 0 ); if (param.isJavaArrayType() && !param.isLocal()) { const TypeNode &element = *param.elementType(); if (element.isStringType() && !element.isLocal()) return true; } } return false; } //////////////////////////////////////////////////////////////////////// void TreeNode::lookForMain() const { undefined( "lookForMain" ); } void CompileUnitNode::lookForMain() const { foriter (type, types()->allChildren(), TreeNode::ChildIter) (*type)->lookForMain(); } void TemplateDeclNode::lookForMain() const { } void ClassDeclNode::lookForMain() const { if (decl()->category() == Decl::Class) foriter (member, members()->allChildren(), TreeNode::ChildIter) (*member)->lookForMain(); } void MethodDeclNode::lookForMain() const { if (isMain()) mainMethods.insert( decl() ); } void InterfaceDeclNode::lookForMain() const { } void FieldDeclNode::lookForMain() const { } void StaticInitNode::lookForMain() const { } void ConstructorDeclNode::lookForMain() const { } void MethodSignatureNode::lookForMain() const { } void OmittedNode::lookForMain() const { } //////////////////////////////////////////////////////////////////////// void checkOnlyOneMain() { switch (mainMethods.size()) { case 0: Error() << "no suitable main() method found in any class" << endl; break; case 1: break; default: Error() << "too many main() methods found" << endl; for (MethodSet::const_iterator method = mainMethods.begin(); method != mainMethods.end(); ++method) (*method)->source()->message() << "candidate " << (*method)->errorName() << "()" << endl; } }