示例#1
0
文件: Parser.cs 项目: knat/SData
 private bool ParsingUnit(string filePath, TextReader reader, LoadingContext context, ClassTypeMd classTypeMd, out object result)
 {
     try
     {
         Init(filePath, reader, context);
         object obj;
         TextSpan textSpan;
         if (ClassValue(classTypeMd, out obj, out textSpan))
         {
             EndOfFileExpected();
             result = obj;
             return true;
         }
         else
         {
             ErrorAndThrow("Class value expected.");
         }
     }
     catch (LoadingException) { }
     finally
     {
         Clear();
     }
     result = null;
     return false;
 }
示例#2
0
文件: Parser.cs 项目: knat/SData
 private bool ClassValue(ClassTypeMd declaredClsMd, out object result, out TextSpan textSpan)
 {
     var hasAliasUriList = false;
     if (Token('<'))
     {
         List<AliasUri> auList = null;
         while (true)
         {
             Token aliasToken;
             if (Name(out aliasToken))
             {
                 var alias = aliasToken.Value;
                 if (auList == null)
                 {
                     auList = new List<AliasUri>();
                 }
                 else
                 {
                     foreach (var item in auList)
                     {
                         if (item.Alias == alias)
                         {
                             ErrorAndThrow(new DiagMsg(DiagnosticCode.DuplicateUriAlias, alias), aliasToken.TextSpan);
                         }
                     }
                 }
                 TokenExpected('=');
                 auList.Add(new AliasUri(alias, StringExpected().Value));
                 if (!Token(','))
                 {
                     break;
                 }
             }
             else
             {
                 break;
             }
         }
         TokenExpected('>');
         if (auList != null)
         {
             _aliasUriListStack.Push(auList);
             hasAliasUriList = true;
         }
     }
     var hasTypeIndicator = false;
     ClassTypeMd clsMd = null;
     var fullName = default(FullName);
     if (Token('('))
     {
         hasTypeIndicator = true;
         var aliasToken = NameExpected();
         TokenExpected((int)TokenKind.ColonColon, ":: expected.");
         var nameToken = NameExpected();
         TokenExpected(')');
         fullName = new FullName(GetUri(aliasToken), nameToken.Value);
         textSpan = nameToken.TextSpan;
         if (declaredClsMd != null)
         {
             clsMd = ProgramMd.TryGetGlobalType<ClassTypeMd>(fullName);
             if (clsMd == null)
             {
                 ErrorAndThrow(new DiagMsg(DiagnosticCode.InvalidClassReference, fullName.ToString()), textSpan);
             }
             if (!clsMd.IsEqualToOrDeriveFrom(declaredClsMd))
             {
                 ErrorAndThrow(new DiagMsg(DiagnosticCode.ClassNotEqualToOrDeriveFromTheDeclared, fullName.ToString(), declaredClsMd.FullName.ToString()),
                     textSpan);
             }
         }
     }
     else
     {
         textSpan = default(TextSpan);
     }
     Token openBraceToken;
     if (Token('{', out openBraceToken))
     {
         if (!hasTypeIndicator)
         {
             textSpan = openBraceToken.TextSpan;
         }
     }
     else
     {
         if (hasAliasUriList || hasTypeIndicator)
         {
             ErrorAndThrow("{ expected.");
         }
         result = null;
         return false;
     }
     if (declaredClsMd != null)
     {
         if (!hasTypeIndicator)
         {
             clsMd = declaredClsMd;
             fullName = declaredClsMd.FullName;
         }
         if (clsMd.IsAbstract)
         {
             ErrorAndThrow(new DiagMsg(DiagnosticCode.ClassIsAbstract, fullName.ToString()), textSpan);
         }
         var obj = clsMd.CreateInstance();
         if (!clsMd.InvokeOnLoad(true, obj, _context, textSpan))
         {
             Throw();
         }
         var propMdMap = clsMd._propertyMap;
         HashSet<string> propNameSet = null;
         Dictionary<string, object> unknownPropMap = null;
         while (true)
         {
             Token propNameToken;
             if (Name(out propNameToken))
             {
                 var propName = propNameToken.Value;
                 if (propNameSet == null)
                 {
                     propNameSet = new HashSet<string>();
                 }
                 else if (propNameSet.Contains(propName))
                 {
                     ErrorAndThrow(new DiagMsg(DiagnosticCode.DuplicatePropertyName, propName), propNameToken.TextSpan);
                 }
                 propNameSet.Add(propName);
                 TokenExpected('=');
                 PropertyMd propMd;
                 if (propMdMap.TryGetValue(propName, out propMd))
                 {
                     propMd.SetValue(obj, LocalValueExpected(propMd.Type));
                 }
                 else
                 {
                     if (unknownPropMap == null)
                     {
                         unknownPropMap = new Dictionary<string, object>();
                     }
                     unknownPropMap.Add(propName, LocalValueExpected(null));
                 }
                 if (!Token(','))
                 {
                     break;
                 }
             }
             else
             {
                 break;
             }
         }
         var closeBraceToken = TokenExpected('}');
         if (propMdMap.Count > 0)
         {
             var needThrow = false;
             foreach (var propMd in propMdMap.Values)
             {
                 if (!propMd.Type.IsNullable && (propNameSet == null || !propNameSet.Contains(propMd.Name)))
                 {
                     Error(new DiagMsg(DiagnosticCode.PropertyMissing, propMd.Name), closeBraceToken.TextSpan);
                     needThrow = true;
                 }
             }
             if (needThrow)
             {
                 Throw();
             }
         }
         if (unknownPropMap != null)
         {
             clsMd.SetUnknownProperties(obj, unknownPropMap);
         }
         if (!clsMd.InvokeOnLoad(false, obj, _context, textSpan))
         {
             Throw();
         }
         result = obj;
     }
     else
     {
         Dictionary<string, object> propMap = null;
         while (true)
         {
             Token propNameToken;
             if (Name(out propNameToken))
             {
                 var propName = propNameToken.Value;
                 if (propMap == null)
                 {
                     propMap = new Dictionary<string, object>();
                 }
                 else if (propMap.ContainsKey(propName))
                 {
                     ErrorAndThrow(new DiagMsg(DiagnosticCode.DuplicatePropertyName, propName), propNameToken.TextSpan);
                 }
                 TokenExpected('=');
                 propMap.Add(propName, LocalValueExpected(null));
                 if (!Token(','))
                 {
                     break;
                 }
             }
             else
             {
                 break;
             }
         }
         TokenExpected('}');
         result = new UntypedObject(fullName, propMap);
     }
     if (hasAliasUriList)
     {
         _aliasUriListStack.Pop();
     }
     return true;
 }
示例#3
0
文件: Parser.cs 项目: knat/SData
 public static bool Parse(string filePath, TextReader reader, LoadingContext context, ClassTypeMd classTypeMd, out object result)
 {
     if (classTypeMd == null) throw new ArgumentNullException("classTypeMd");
     return Instance.ParsingUnit(filePath, reader, context, classTypeMd, out result);
 }