feat: recognize indirect asset refs when marking assets

This commit is contained in:
Jan
2024-02-07 00:53:52 +01:00
parent 2dd4eaf54f
commit fef815e708
14 changed files with 175 additions and 10 deletions

View File

@ -6,6 +6,7 @@
#include "Parsing/Commands/Sequence/SequenceArrayCount.h"
#include "Parsing/Commands/Sequence/SequenceArraySize.h"
#include "Parsing/Commands/Sequence/SequenceAsset.h"
#include "Parsing/Commands/Sequence/SequenceAssetRef.h"
#include "Parsing/Commands/Sequence/SequenceBlock.h"
#include "Parsing/Commands/Sequence/SequenceCondition.h"
#include "Parsing/Commands/Sequence/SequenceCount.h"
@ -33,6 +34,7 @@ const std::vector<CommandsParser::sequence_t*>& CommandsParser::GetTestsForState
new SequenceArrayCount(),
new SequenceArraySize(),
new SequenceAsset(),
new SequenceAssetRef(),
new SequenceBlock(),
new SequenceCondition(),
new SequenceCount(),

View File

@ -0,0 +1,72 @@
#include "SequenceAssetRef.h"
#include "Parsing/Commands/Matcher/CommandsCommonMatchers.h"
#include "Parsing/Commands/Matcher/CommandsMatcherFactory.h"
#include <algorithm>
SequenceAssetRef::SequenceAssetRef()
{
const CommandsMatcherFactory create(this);
AddLabeledMatchers(CommandsCommonMatchers::Typename(this), CommandsCommonMatchers::LABEL_TYPENAME);
AddMatchers({
create.Keyword("set"),
create.Keyword("assetref"),
create.Label(CommandsCommonMatchers::LABEL_TYPENAME).Capture(CAPTURE_TYPE),
create.Identifier().Capture(CAPTURE_ASSET_TYPE_ENUM_ENTRY),
create.Char(';'),
});
}
void SequenceAssetRef::ProcessMatch(CommandsParserState* state, SequenceResult<CommandsParserValue>& result) const
{
const auto& enumEntryToken = result.NextCapture(CAPTURE_ASSET_TYPE_ENUM_ENTRY);
const auto* enumMember = state->GetRepository()->GetEnumMemberByName(enumEntryToken.IdentifierValue());
if (enumMember == nullptr)
throw ParsingException(enumEntryToken.GetPos(), "Unknown asset type enum entry");
const auto& typeNameToken = result.NextCapture(CAPTURE_TYPE);
StructureInformation* type;
std::vector<MemberInformation*> members;
if (!state->GetTypenameAndMembersFromTypename(typeNameToken.TypeNameValue(), type, members))
throw ParsingException(typeNameToken.GetPos(), "Unknown type");
if (members.empty())
throw ParsingException(typeNameToken.GetPos(), "Need to specify a member when trying to mark as string.");
auto* lastMember = members.back();
const auto* typeDecl = lastMember->m_member->m_type_declaration.get();
auto hasPointerRef = false;
while (true)
{
if (!hasPointerRef)
{
const auto& modifiers = typeDecl->m_declaration_modifiers;
hasPointerRef = std::any_of(modifiers.begin(),
modifiers.end(),
[](const std::unique_ptr<DeclarationModifier>& modifier)
{
return modifier->GetType() == DeclarationModifierType::POINTER;
});
}
if (typeDecl->m_type->GetType() == DataDefinitionType::TYPEDEF)
{
const auto* typedefDef = dynamic_cast<const TypedefDefinition*>(typeDecl->m_type);
typeDecl = typedefDef->m_type_declaration.get();
}
else
break;
}
if (!hasPointerRef)
throw ParsingException(typeNameToken.GetPos(), "Invalid type for string, must be a pointer");
if (typeDecl->m_type->GetType() != DataDefinitionType::BASE_TYPE)
throw ParsingException(typeNameToken.GetPos(), "Invalid type for string, must be a base type");
lastMember->m_asset_ref = enumMember;
}

View File

@ -0,0 +1,17 @@
#pragma once
#include "Parsing/Commands/Impl/CommandsParser.h"
class SequenceAssetRef final : public CommandsParser::sequence_t
{
static constexpr auto TAG_DEFAULT = 1;
static constexpr auto CAPTURE_TYPE = 1;
static constexpr auto CAPTURE_ASSET_TYPE_ENUM_ENTRY = 2;
protected:
void ProcessMatch(CommandsParserState* state, SequenceResult<CommandsParserValue>& result) const override;
public:
SequenceAssetRef();
};

View File

@ -44,8 +44,8 @@ bool MarkingRequiredPostProcessor::CalculateRequiresMarking(std::unordered_set<c
if (skip)
continue;
// Any ScriptStrings or Strings need to be processed.
if (member->m_is_script_string || member->m_type && member->m_type->m_asset_enum_entry)
// Any script strings, asset refs and assets need to be processed.
if (member->m_is_script_string || member->m_asset_ref || member->m_type && member->m_type->m_asset_enum_entry)
{
info->m_requires_marking = true;
return true;