| 254 | } |
| 255 | |
| 256 | std::vector<EventDefinition const*> Natspec::uniqueInterfaceEvents(ContractDefinition const& _contract) |
| 257 | { |
| 258 | auto eventSignature = [](EventDefinition const* _event) -> std::string { |
| 259 | FunctionType const* functionType = _event->functionType(true); |
| 260 | solAssert(functionType, ""); |
| 261 | return functionType->externalSignature(); |
| 262 | }; |
| 263 | auto compareBySignature = |
| 264 | [&](EventDefinition const* _lhs, EventDefinition const* _rhs) -> bool { |
| 265 | return eventSignature(_lhs) < eventSignature(_rhs); |
| 266 | }; |
| 267 | |
| 268 | std::set<EventDefinition const*, decltype(compareBySignature)> uniqueEvents{compareBySignature}; |
| 269 | // Insert events defined in the contract first so that in case of a conflict |
| 270 | // they're the ones that get selected. |
| 271 | uniqueEvents += _contract.definedInterfaceEvents(); |
| 272 | |
| 273 | std::set<EventDefinition const*, decltype(compareBySignature)> filteredUsedEvents{compareBySignature}; |
| 274 | std::set<std::string> usedSignatures; |
| 275 | for (EventDefinition const* event: _contract.usedInterfaceEvents()) |
| 276 | { |
| 277 | auto&& [eventIt, eventInserted] = filteredUsedEvents.insert(event); |
| 278 | auto&& [signatureIt, signatureInserted] = usedSignatures.insert(eventSignature(event)); |
| 279 | if (!signatureInserted) |
| 280 | filteredUsedEvents.erase(eventIt); |
| 281 | } |
| 282 | |
| 283 | uniqueEvents += filteredUsedEvents; |
| 284 | return util::convertContainer<std::vector<EventDefinition const*>>(std::move(uniqueEvents)); |
| 285 | } |
nothing calls this directly
no test coverage detected