예제 #1
0
        //note: the value is unescaped, so offsets within it are not valid
        void VisitPureLiteral(ValueInfo info, MSBuildValueKind kind, string value, int offset)
        {
            IReadOnlyList <ConstantInfo> knownVals = info.Values ?? kind.GetSimpleValues(false);

            if (knownVals != null && knownVals.Count != 0)
            {
                foreach (var kv in knownVals)
                {
                    if (string.Equals(kv.Name, value, StringComparison.OrdinalIgnoreCase))
                    {
                        return;
                    }
                }
                AddErrorWithArgs(CoreDiagnostics.UnknownValue, DescriptionFormatter.GetKindNoun(info), info.Name, value);
                return;
            }
            switch (kind)
            {
            case MSBuildValueKind.Guid:
            case MSBuildValueKind.ProjectKindGuid:
                if (!Guid.TryParseExact(value, "B", out _))
                {
                    AddErrorWithArgs(CoreDiagnostics.InvalidGuid, value);
                }
                break;

            case MSBuildValueKind.Int:
                if (!long.TryParse(value, out _))
                {
                    AddErrorWithArgs(CoreDiagnostics.InvalidInteger, value);
                }
                break;

            case MSBuildValueKind.Bool:
                if (!bool.TryParse(value, out _))
                {
                    AddErrorWithArgs(CoreDiagnostics.InvalidBool, value);
                }
                break;

            case MSBuildValueKind.Url:
                if (!Uri.TryCreate(value, UriKind.Absolute, out _))
                {
                    AddErrorWithArgs(CoreDiagnostics.InvalidUrl, value);
                }
                break;

            case MSBuildValueKind.Version:
                if (!Version.TryParse(value, out _))
                {
                    AddErrorWithArgs(CoreDiagnostics.InvalidVersion, value);
                }
                break;

            /*
             * FIXME: these won't work as-is, as inference will add them to the schema
             * case MSBuildValueKind.TargetName:
             *      if (Document.GetSchemas ().GetTarget (value) == null) {
             *              AddErrorWithArgs (CoreDiagnostics.UndefinedTarget, value);
             *      }
             *      break;
             * case MSBuildValueKind.PropertyName:
             *      if (Document.GetSchemas ().GetProperty (value) == null) {
             *              AddErrorWithArgs (CoreDiagnostics.UnknownProperty, value);
             *      }
             *      break;
             * case MSBuildValueKind.ItemName:
             *      if (Document.GetSchemas ().GetItem (value) == null) {
             *              AddErrorWithArgs (CoreDiagnostics.UnknownProperty, value);
             *      }
             *      break;
             */
            case MSBuildValueKind.Lcid:
                if (int.TryParse(value, out int lcid) && lcid > 0)
                {
                    try {
                        CultureInfo.GetCultureInfo(lcid);
                    } catch (CultureNotFoundException) {
                        AddErrorWithArgs(CoreDiagnostics.UnknownLcid, value);
                    }
                }
                else
                {
                    AddErrorWithArgs(CoreDiagnostics.InvalidLcid, value);
                }
                break;

            case MSBuildValueKind.TargetFramework:
                if (!FrameworkInfoProvider.Instance.IsFrameworkShortNameValid(value))
                {
                    AddErrorWithArgs(CoreDiagnostics.UnknownTargetFramework, value);
                }
                break;

            case MSBuildValueKind.TargetFrameworkIdentifier:
                if (!FrameworkInfoProvider.Instance.IsFrameworkIdentifierValid(value))
                {
                    AddErrorWithArgs(CoreDiagnostics.UnknownTargetFrameworkIdentifier, value);
                }
                break;

            case MSBuildValueKind.TargetFrameworkVersion: {
                if (!Version.TryParse(value.TrimStart('v', 'V'), out Version fxv))
                {
                    AddErrorWithArgs(CoreDiagnostics.InvalidVersion, value);
                    break;
                }
                fxv = new Version(Math.Max(fxv.Major, 0), Math.Max(fxv.Minor, 0), Math.Max(fxv.Revision, 0), Math.Max(fxv.Build, 0));
                if (Document is MSBuildRootDocument d && d.Frameworks.Count > 0)
                {
                    bool foundMatch = false;
                    foreach (var fx in d.Frameworks)
                    {
                        if (FrameworkInfoProvider.AreVersionsEquivalent(fx.Version, fxv) && FrameworkInfoProvider.Instance.IsFrameworkVersionValid(fx.Framework, fxv))
                        {
                            foundMatch = true;
                        }
                    }
                    if (!foundMatch)
                    {
                        AddErrorWithArgs(CoreDiagnostics.UnknownTargetFrameworkVersion, value, d.Frameworks[0].Framework);
                    }
                }
                break;
            }

            case MSBuildValueKind.TargetFrameworkProfile: {
                if (Document is MSBuildRootDocument d && d.Frameworks.Count > 0)
                {
                    bool foundMatch = false;
                    foreach (var fx in d.Frameworks)
                    {
                        if (fx.Profile == value && FrameworkInfoProvider.Instance.IsFrameworkProfileValid(fx.Framework, fx.Version, value))
                        {
                            foundMatch = true;
                        }
                    }
                    if (!foundMatch)
                    {
                        AddErrorWithArgs(CoreDiagnostics.UnknownTargetFrameworkProfile, value, d.Frameworks[0].Framework, d.Frameworks[0].Version);
                    }
                }
                break;
            }
            }

            void AddError(MSBuildDiagnosticDescriptor d) => Document.Diagnostics.Add(d, new TextSpan(offset, value.Length));
            void AddErrorWithArgs(MSBuildDiagnosticDescriptor d, params object[] args) => Document.Diagnostics.Add(d, new TextSpan(offset, value.Length), args);
        }