internal static MemberAst Parse(ParserStream stream, QualifierListAst qualifiers) { var type = stream.Read<IdentifierToken>(); bool isRef; if (stream.PeekKeyword("ref")) { stream.ReadKeyword("ref"); isRef = true; } else { isRef = false; } var name = stream.Read<IdentifierToken>(); if (stream.Peek<OpenParenthesesToken>() != null && !isRef) { var ast = new MethodAst { Qualifiers = qualifiers, Name = name.Name, ReturnType = type.Name }; stream.Read<OpenParenthesesToken>(); while (!stream.Eof) { if (stream.Peek<CloseParenthesesToken>() != null) break; QualifierListAst argQualifiers = null; if (stream.Peek<AttributeOpenToken>() != null) { argQualifiers = QualifierListAst.Parse(stream); } var argument = new MethodAst.Argument { Qualifiers = argQualifiers }; argument.Type = stream.Read<IdentifierToken>().Name; if (stream.PeekKeyword("ref")) { stream.ReadKeyword("ref"); argument.IsRef = true; } else { argument.IsRef = false; } argument.Name = stream.Read<IdentifierToken>().Name; if (stream.Peek<AttributeOpenToken>() != null) { stream.Read<AttributeOpenToken>(); stream.Read<AttributeCloseToken>(); } if (stream.Peek<EqualsOperatorToken>() != null) { stream.Read<EqualsOperatorToken>(); argument.DefaultValue = LiteralValueAst.Parse(stream); } ast.Arguments.Add(argument); if (stream.Peek<CommaToken>() == null) break; stream.Read<CommaToken>(); } stream.Read<CloseParenthesesToken>(); stream.Read<StatementEndToken>(); return ast; } else { var ast = new FieldAst { Qualifiers = qualifiers, Name = name.Name, Type = type.Name, IsRef = isRef }; if (stream.Peek<AttributeOpenToken>() != null) { stream.Read<AttributeOpenToken>(); stream.Read<AttributeCloseToken>(); ast.IsArray = true; } if (stream.Peek<EqualsOperatorToken>() != null) { stream.Read<EqualsOperatorToken>(); ast.Initializer = LiteralValueAst.Parse(stream); } stream.Read<StatementEndToken>(); return ast; } }
/// <summary> /// </summary> /// <returns></returns> /// <remarks> /// /// See http://www.dmtf.org/sites/default/files/standards/documents/DSP0221_3.0.0a.pdf /// A.14 Complex type value /// /// complexTypeValue = complexValue / complexValueArray /// complexValueArray = "{" [ complexValue *( "," complexValue) ] "}" /// complexValue = ( INSTANCE / VALUE ) OF /// ( structureName / className / associationName ) /// [ alias ] propertyValueList ";" /// propertyValueList = "{" *propertySlot "}" /// propertySlot = propertyName "=" propertyValue ";" /// propertyValue = primitiveTypeValue / complexTypeValue / referenceTypeValue / enumTypeValue /// alias = AS aliasIdentifier /// INSTANCE = "instance" ; keyword: case insensitive /// VALUE = "value" ; keyword: case insensitive /// AS = "as" ; keyword: case insensitive /// OF = "of" ; keyword: case insensitive /// /// propertyName = IDENTIFIER /// /// </remarks> internal static new ComplexValueAst Parse(ParserStream stream) { // complexValue = var node = new ComplexValueAst(); // ( INSTANCE / VALUE ) var keyword = stream.ReadKeyword(); switch (keyword.Name) { case "instance": node.IsInstance = true; node.IsValue = false; break; case "value": node.IsInstance = false; node.IsValue = true; break; default: throw new InvalidOperationException(); } // OF stream.ReadKeyword("of"); // ( structureName / className / associationName ) node.TypeName = stream.Read<IdentifierToken>().Name; // [ alias ] if (stream.PeekKeyword("as")) { stream.ReadKeyword("as"); // BUGBUG - PowerShell DSC MOFs allow schema names in an alias identifier //node.Alias = NameValidator.ValidateAliasIdentifier("$" + stream.Read<AliasIdentifierToken>().Name); node.Alias = stream.Read<AliasIdentifierToken>().Name; } // propertyValueList stream.Read<BlockOpenToken>(); while (!stream.Eof && (stream.Peek<BlockCloseToken>() == null)) { // propertyName var propertyName = NameValidator.ValidateIdentifier(stream.Read<IdentifierToken>().Name); // "=" stream.Read<EqualsOperatorToken>(); // propertyValue var propertyValue = PropertyValueAst.Parse(stream); // ";" stream.Read<StatementEndToken>(); node.Properties.Add(propertyName, propertyValue); } // "}" stream.Read<BlockCloseToken>(); // ";" stream.Read<StatementEndToken>(); // return the result return node; }