// Reads a new-style value //@TODO: UCREMOVAL: Needs a better name FString FBaseParser::ReadNewStyleValue(const FString& TypeOfSpecifier) { FToken ValueToken; if (!GetToken( ValueToken, false )) FError::Throwf(TEXT("Expected a value when handling a "), *TypeOfSpecifier); switch (ValueToken.TokenType) { case TOKEN_Identifier: case TOKEN_Symbol: { FString Result = ValueToken.Identifier; if (MatchSymbol(TEXT("="))) { Result += TEXT("="); Result += ReadNewStyleValue(TypeOfSpecifier); } return Result; } case TOKEN_Const: return ValueToken.GetConstantValue(); default: return TEXT(""); } }
// // Require a symbol. // void FBaseParser::RequireSymbol( const TCHAR* Match, const TCHAR* Tag, ESymbolParseOption bParseTemplateClosingBracket/*=ESymbolParseOption::Normal*/ ) { if (!MatchSymbol(Match, bParseTemplateClosingBracket)) { FError::Throwf(TEXT("Missing '%s' in %s"), Match, Tag ); } }
// // Require a symbol. // void FBaseParser::RequireSymbol( const TCHAR* Match, const TCHAR* Tag ) { if (!MatchSymbol(Match)) { FError::Throwf(TEXT("Missing '%s' in %s"), Match, Tag ); } }
// Reads [ Value | ['(' Value [',' Value]* ')'] ] and places each value into the Items array bool FBaseParser::ReadOptionalCommaSeparatedListInParens(TArray<FString>& Items, const FString& TypeOfSpecifier) { if (MatchSymbol(TEXT("("))) { do { FString Value = ReadNewStyleValue(TypeOfSpecifier); Items.Add(Value); } while ( MatchSymbol(TEXT(",")) ); RequireSymbol(TEXT(")"), *TypeOfSpecifier); return true; } return false; }
//------------------------------------------------------------------------------ bool FBasicTokenParser::RequireSymbol(TCHAR const* Match, TCHAR const* ErrorContext) { if (!MatchSymbol(Match)) { FText ErrorDesc = FText::Format(LOCTEXT("MissingRequirement", "Missing '{0}' in {1}"), FText::FromString(Match), FText::FromString(ErrorContext)); SetError(FErrorState::RequireError, ErrorDesc); } return IsValid(); }
void FBaseParser::MatchSemi() { if( !MatchSymbol(TEXT(";")) ) { FToken Token; if( GetToken(Token) ) { FError::Throwf(TEXT("Missing ';' before '%s'"), Token.Identifier ); } else { FError::Throwf(TEXT("Missing ';'") ); } } }
//------------------------------------------------------------------------------ bool FBasicTokenParser::RequireSemi() { if( !MatchSymbol(TEXT(";")) ) { FText ErrorDesc = LOCTEXT("MissingSemiColon", "Missing ';'"); FBasicToken Token; if( GetToken(Token) ) { ErrorDesc = FText::Format(LOCTEXT("MissingSemiBefore", "Missing ';' before '{0}'"), FText::FromString(Token.Identifier)); } SetError(FErrorState::RequireError, ErrorDesc); } return IsValid(); }
// Reads a set of specifiers (with optional values) inside the () of a new-style metadata macro like UPROPERTY or UFUNCTION void FBaseParser::ReadSpecifierSetInsideMacro(TArray<FPropertySpecifier>& SpecifiersFound, const FString& TypeOfSpecifier, TMap<FName, FString>& MetaData) { int32 FoundSpecifierCount = 0; FString ErrorMessage = FString::Printf(TEXT("%s declaration specifier"), *TypeOfSpecifier); RequireSymbol(TEXT("("), *ErrorMessage); while (!MatchSymbol(TEXT(")"))) { if (FoundSpecifierCount > 0) { RequireSymbol(TEXT(","), *ErrorMessage); } ++FoundSpecifierCount; // Read the specifier key FToken Specifier; if (!GetToken(Specifier)) { FError::Throwf(TEXT("Expected %s"), *ErrorMessage); } if (Specifier.Matches(TEXT("meta"))) { RequireSymbol(TEXT("="), *ErrorMessage); RequireSymbol(TEXT("("), *ErrorMessage); // Keep reading comma-separated metadata pairs do { // Read a key FToken MetaKeyToken; if (!GetIdentifier(MetaKeyToken)) { FError::Throwf(TEXT("Expected a metadata key")); } FString Key = MetaKeyToken.Identifier; // Potentially read a value FString Value; if (MatchSymbol(TEXT("="))) { Value = ReadNewStyleValue(TypeOfSpecifier); } // Validate the value is a valid type for the key and insert it into the map InsertMetaDataPair(MetaData, Key, Value); } while ( MatchSymbol(TEXT(",")) ); RequireSymbol(TEXT(")"), *ErrorMessage); } // Look up specifier in metadata dictionary else if (FMetadataKeyword* MetadataKeyword = GetMetadataKeyword(Specifier.Identifier)) { if (MatchSymbol(TEXT("="))) { if (MetadataKeyword->ValueArgument == EMetadataValueArgument::None) { FError::Throwf(TEXT("Incorrect = after metadata specifier '%s'"), Specifier.Identifier); } FString Value = ReadNewStyleValue(TypeOfSpecifier); MetadataKeyword->ApplyToMetadata(MetaData, &Value); } else { if (MetadataKeyword->ValueArgument == EMetadataValueArgument::Required) { FError::Throwf(TEXT("Missing = after metadata specifier '%s'"), Specifier.Identifier); } MetadataKeyword->ApplyToMetadata(MetaData); } } else { // Creating a new specifier SpecifiersFound.Emplace(Specifier.Identifier); // Look for a value for this specifier if (MatchSymbol(TEXT("=")) || PeekSymbol(TEXT("("))) { TArray<FString>& NewPairValues = SpecifiersFound.Last().Values; if (!ReadOptionalCommaSeparatedListInParens(NewPairValues, TypeOfSpecifier)) { FString Value = ReadNewStyleValue(TypeOfSpecifier); NewPairValues.Add(Value); } } } } }