Example #1
0
 public static ServiceMemberInfo GetMemberReferencedAtPosition(this ServiceInfo service, Position requestPosition)
 {
     return((
                from field in service.GetDescendants().OfType <ServiceFieldInfo>()
                let part = field.GetPart(ServicePartKind.TypeName)
                           where part != null && requestPosition >= part.Position && requestPosition < part.EndPosition
                           let type = service.GetFieldType(field)
                                      where type != null
                                      let name = type.GetMemberTypeName()
                                                 where name != null
                                                 select service.FindMember(name)).FirstOrDefault());
 }
Example #2
0
        /// <summary>
        /// Implements TryParseDefinition.
        /// </summary>
        protected override bool TryParseDefinitionCore(ServiceDefinitionText source, out ServiceInfo service, out IReadOnlyList <ServiceDefinitionError> errors)
        {
            var errorList                  = new List <ServiceDefinitionError>();
            var definitionLines            = new List <string>();
            var remarksSectionsByName      = new Dictionary <string, FsdRemarksSection>(StringComparer.OrdinalIgnoreCase);
            var interleavedRemarksSections = new List <FsdRemarksSection>();

            if (!s_interleavedMarkdown.IsMatch(source.Text))
            {
                ReadRemarksAfterDefinition(source, definitionLines, remarksSectionsByName, errorList);
            }
            else
            {
                ReadInterleavedRemarks(source, definitionLines, interleavedRemarksSections, errorList);
            }

            source  = new ServiceDefinitionText(source.Name, string.Join("\n", definitionLines));
            service = null;

            try
            {
                service = FsdParsers.ParseDefinition(source, remarksSectionsByName);
                errorList.AddRange(service.GetValidationErrors());

                // check for unused remarks sections
                foreach (var remarksSectionPair in remarksSectionsByName)
                {
                    string sectionName = remarksSectionPair.Key;
                    if (service.Name != sectionName && service.FindMember(sectionName) == null)
                    {
                        errorList.Add(new ServiceDefinitionError($"Unused remarks heading: {sectionName}", remarksSectionPair.Value.Position));
                    }
                }

                // check for interleaved remarks sections
                foreach (var remarksSection in interleavedRemarksSections)
                {
                    var remarksLineNumber = remarksSection.Position.LineNumber;
                    if (remarksLineNumber > service.GetPart(ServicePartKind.Name).Position.LineNumber&&
                        remarksLineNumber < service.GetPart(ServicePartKind.End).Position.LineNumber)
                    {
                        ServiceMemberInfo targetMember = service;
                        int targetLineNumber           = 0;
                        foreach (var member in service.Members)
                        {
                            int memberLineNumber = member.GetPart(ServicePartKind.Name).Position.LineNumber;
                            if (remarksLineNumber > memberLineNumber && memberLineNumber > targetLineNumber)
                            {
                                targetMember     = member;
                                targetLineNumber = memberLineNumber;
                            }
                        }

                        if (targetMember.Remarks.Count == 0)
                        {
                            targetMember.Remarks = remarksSection.Lines;
                        }
                        else
                        {
                            targetMember.Remarks = targetMember.Remarks.Concat(new[] { "" }).Concat(remarksSection.Lines).ToList();
                        }
                    }
                }
            }
            catch (ParseException exception)
            {
                var expectation = exception
                                  .Result
                                  .GetNamedFailures()
                                  .Distinct()
                                  .GroupBy(x => x.Position)
                                  .Select(x => new { LineColumn = x.Key.GetLineColumn(), Names = x.Select(y => y.Name) })
                                  .OrderByDescending(x => x.LineColumn.LineNumber)
                                  .ThenByDescending(x => x.LineColumn.ColumnNumber)
                                  .First();

                int getExpectationNameRank(string name) => name == "')'" || name == "']'" || name == "'}'" || name == "';'" ? 1 : 2;

                errorList.Add(new ServiceDefinitionError(
                                  "expected " + string.Join(" or ", expectation.Names.Distinct().OrderBy(getExpectationNameRank).ThenBy(x => x, StringComparer.Ordinal)),
                                  new ServiceDefinitionPosition(source.Name, expectation.LineColumn.LineNumber, expectation.LineColumn.ColumnNumber)));
            }

            errors = errorList;
            return(errorList.Count == 0);
        }