Example #1
0
File: Parser.cs Project: knat/SData
 private object LocalValueExpected(LocalTypeMd typeMd)
 {
     object value;
     TextSpan textSpan;
     if (!LocalValue(typeMd, out value, out textSpan))
     {
         ErrorAndThrow(new DiagMsg(DiagnosticCode.ValueExpected));
     }
     return value;
 }
Example #2
0
File: Parser.cs Project: knat/SData
 private bool LocalValue(LocalTypeMd typeMd, out object result, out TextSpan textSpan)
 {
     Token token;
     if (Null(out token))
     {
         if (typeMd != null && !typeMd.IsNullable)
         {
             ErrorAndThrow(new DiagMsg(DiagnosticCode.NullNotAllowed), token.TextSpan);
         }
         result = null;
         textSpan = token.TextSpan;
         return true;
     }
     if (AtomValue(out token))
     {
         if (typeMd != null)
         {
             var nonNullableTypeMd = typeMd.NonNullableType;
             var typeKind = nonNullableTypeMd.Kind;
             if (!typeKind.IsAtom())
             {
                 if (typeKind == TypeKind.Enum)
                 {
                     typeKind = nonNullableTypeMd.TryGetGlobalType<EnumTypeMd>().UnderlyingType.Kind;
                 }
                 else
                 {
                     ErrorAndThrow(new DiagMsg(DiagnosticCode.SpecificValueExpected, typeKind.ToString()), token.TextSpan);
                 }
             }
             result = AtomExtensions.TryParse(typeKind, token.Value);
             if (result == null)
             {
                 ErrorAndThrow(new DiagMsg(DiagnosticCode.InvalidAtomValue, typeKind.ToString(), token.Value), token.TextSpan);
             }
         }
         else
         {
             result = token.Value;
         }
         textSpan = token.TextSpan;
         return true;
     }
     if (PeekToken('(', '{', '<'))
     {//class value
         if (typeMd != null)
         {
             var nonNullableTypeMd = typeMd.NonNullableType;
             var typeKind = nonNullableTypeMd.Kind;
             if (typeKind != TypeKind.Class)
             {
                 ErrorAndThrow(new DiagMsg(DiagnosticCode.SpecificValueExpected, typeKind.ToString()));
             }
             return ClassValue(nonNullableTypeMd.TryGetGlobalType<ClassTypeMd>(), out result, out textSpan);
         }
         else
         {
             return ClassValue(null, out result, out textSpan);
         }
     }
     if (Name(out token))
     {//enum value
         TokenExpected((int)TokenKind.ColonColon, ":: expected.");
         var nameToken = NameExpected();
         var fullName = new FullName(GetUri(token), nameToken.Value);
         EnumTypeMd enumMd = null;
         if (typeMd != null)
         {
             var nonNullableTypeMd = typeMd.NonNullableType;
             var typeKind = nonNullableTypeMd.Kind;
             if (typeKind != TypeKind.Enum)
             {
                 ErrorAndThrow(new DiagMsg(DiagnosticCode.SpecificValueExpected, typeKind.ToString()), nameToken.TextSpan);
             }
             enumMd = ProgramMd.TryGetGlobalType<EnumTypeMd>(fullName);
             if (enumMd == null)
             {
                 ErrorAndThrow(new DiagMsg(DiagnosticCode.InvalidEnumReference, fullName.ToString()), nameToken.TextSpan);
             }
             var declaredEnumMd = nonNullableTypeMd.TryGetGlobalType<EnumTypeMd>();
             if (enumMd != declaredEnumMd)
             {
                 ErrorAndThrow(new DiagMsg(DiagnosticCode.EnumNotEqualToTheDeclared, fullName.ToString(), declaredEnumMd.FullName.ToString()),
                     nameToken.TextSpan);
             }
         }
         TokenExpected('.');
         var memberNameToken = NameExpected();
         if (enumMd != null)
         {
             if (!enumMd._members.TryGetValue(memberNameToken.Value, out result))
             {
                 ErrorAndThrow(new DiagMsg(DiagnosticCode.InvalidEnumMemberName, memberNameToken.Value), memberNameToken.TextSpan);
             }
         }
         else
         {
             result = new UntypedEnumValue(fullName, memberNameToken.Value);
         }
         textSpan = memberNameToken.TextSpan;
         return true;
     }
     if (Token('[', out token))
     {
         if (typeMd != null)
         {
             var nonNullableTypeMd = typeMd.NonNullableType;
             var typeKind = nonNullableTypeMd.Kind;
             var isSet = typeKind == TypeKind.Set;
             if (typeKind != TypeKind.List && !isSet)
             {
                 ErrorAndThrow(new DiagMsg(DiagnosticCode.SpecificValueExpected, typeKind.ToString()), token.TextSpan);
             }
             var collTypeMd = (CollectionTypeMd)nonNullableTypeMd;
             var collObj = collTypeMd.CreateInstance();
             var itemMd = collTypeMd.ItemOrValueType;
             object itemObj;
             TextSpan ts;
             while (true)
             {
                 if (LocalValue(itemMd, out itemObj, out ts))
                 {
                     if (isSet)
                     {
                         if (!collTypeMd.InvokeBoolAdd(collObj, itemObj))
                         {
                             ErrorAndThrow(new DiagMsg(DiagnosticCode.DuplicateSetItem), ts);
                         }
                     }
                     else
                     {
                         collTypeMd.InvokeAdd(collObj, itemObj);
                     }
                     if (!Token(','))
                     {
                         break;
                     }
                 }
                 else
                 {
                     break;
                 }
             }
             TokenExpected(']');
             result = collObj;
         }
         else
         {
             var listObj = new List<object>();
             object itemObj;
             TextSpan ts;
             while (true)
             {
                 if (LocalValue(null, out itemObj, out ts))
                 {
                     listObj.Add(itemObj);
                     if (!Token(','))
                     {
                         break;
                     }
                 }
                 else
                 {
                     break;
                 }
             }
             TokenExpected(']');
             result = listObj;
         }
         textSpan = token.TextSpan;
         return true;
     }
     if (Token((int)TokenKind.DollarOpenBracket, out token))
     {
         if (typeMd != null)
         {
             var nonNullableTypeMd = typeMd.NonNullableType;
             var typeKind = nonNullableTypeMd.Kind;
             if (typeKind != TypeKind.Map)
             {
                 ErrorAndThrow(new DiagMsg(DiagnosticCode.SpecificValueExpected, typeKind.ToString()), token.TextSpan);
             }
             var collTypeMd = (CollectionTypeMd)nonNullableTypeMd;
             var collObj = collTypeMd.CreateInstance();
             var keyMd = collTypeMd.MapKeyType;
             var valueMd = collTypeMd.ItemOrValueType;
             object keyObj;
             TextSpan ts;
             while (true)
             {
                 if (LocalValue(keyMd, out keyObj, out ts))
                 {
                     if (collTypeMd.InvokeContainsKey(collObj, keyObj))
                     {
                         ErrorAndThrow(new DiagMsg(DiagnosticCode.DuplicateMapKey), ts);
                     }
                     TokenExpected('=');
                     collTypeMd.InvokeAdd(collObj, keyObj, LocalValueExpected(valueMd));
                     if (!Token(','))
                     {
                         break;
                     }
                 }
                 else
                 {
                     break;
                 }
             }
             TokenExpected(']');
             result = collObj;
         }
         else
         {
             var mapObj = new Dictionary<object, object>();
             object keyObj;
             TextSpan ts;
             while (true)
             {
                 if (LocalValue(null, out keyObj, out ts))
                 {
                     TokenExpected('=');
                     mapObj.Add(keyObj, LocalValueExpected(null));
                     if (!Token(','))
                     {
                         break;
                     }
                 }
                 else
                 {
                     break;
                 }
             }
             TokenExpected(']');
             result = mapObj;
         }
         textSpan = token.TextSpan;
         return true;
     }
     result = null;
     textSpan = default(TextSpan);
     return false;
 }