/* Metallurgy - Higher Level Interface to Chordata * Copyright (C) 2001-2002 Jay Freeman (saurik) */ /* * 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. * 3. The name of the author may not be used to endorse * or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. */ #include "stdafx.h" #include "metallurgy/Method.h" #include "metallurgy/TypeDef.h" #include "metallurgy/ILMethodImpl.h" #include "metallurgy/RuntimeMethodImpl.h" namespace Metallurgy { Method::Method(const Module *module, Chordata::Token token) : Member(module, token) { wchar_t buff[1024]; mdTypeDef tktype; uint32_t implflags; uint32_t coderva; const Chordata::Signature *sigBlob; uint32_t sigLength; (*module)->GetMethodProps(token, &tktype, buff, 1024, NULL, &flags, &sigBlob, &sigLength, &coderva, &implflags); name = buff; type = dynamic_cast(module->ResolveToken(tktype)); signature = new Signature(module, sigBlob, sigLength); uint32_t code = implflags & Chordata::Flags::miCodeTypeMask; if (code == Chordata::Flags::miIL) impl = new ILMethodImpl(this, coderva, implflags); else if (code == Chordata::Flags::miRuntime) impl = new RuntimeMethodImpl(this, coderva, implflags); else impl = NULL; } Method::~Method() { delete impl; } const IHasElement *Method::getType() const { return type; } uint32_t Method::getFlags() const { return flags; } const MethodImpl *Method::getImpl() const { return impl; } Chordata::Flags::CorMethodAttr Method::getAccess() const { return (Chordata::Flags::CorMethodAttr) (flags & Chordata::Flags::mdMemberAccessMask); } const Param *Method::getParam(uint32_t sequence) const { mdParamDef tkparam(Chordata::Tokens::NilToken); (*module)->GetParamForMethodIndex(token, sequence, &tkparam); /*if (tkparam == Chordata::Tokens::NilToken) throw std::wstring(L"argument without parameter");*/ return dynamic_cast(module->ResolveToken(tkparam)); } const Element *Method::getArgument(uint32_t sequence) const { if (signature->getHasThis() && (sequence--) == 0) return type->getElement(); else return signature->getElement(sequence); } std::wstring Method::getArgName(uint32_t sequence) const { return (signature->getHasThis() && sequence == 0) ? L"" : getParam(signature->getHasThis() ? sequence : sequence + 1)->getName().getFull(); } std::wstring Method::getXmlMemberKey() const { std::wstring key = L"M:" + type->getName().getFull() + L"." + name.getFull() + L"("; for (uint32_t i(0); i < signature->getCount(); i++) { if (i != 0) key += L","; key += signature->getElement(i)->getXmlMemberKey(); } return key + L")"; } bool Method::IsStatic() const { return (flags & Chordata::Flags::mdStatic) != 0; } bool Method::IsFinal() const { return (flags & Chordata::Flags::mdFinal) != 0; } bool Method::IsVirtual() const { return (flags & Chordata::Flags::mdVirtual) != 0; } bool Method::IsHideBySig() const { return (flags & Chordata::Flags::mdHideBySig) != 0; } bool Method::IsAbstract() const { return (flags & Chordata::Flags::mdAbstract) != 0; } bool Method::IsSpecialName() const { return (flags & Chordata::Flags::mdSpecialName) != 0; } }