Esempio n. 1
0
        protected override void VisitValue(
            XElement element, XAttribute attribute,
            MSBuildElementSyntax resolvedElement, MSBuildAttributeSyntax resolvedAttribute,
            ITypedSymbol valueDescriptor, string value, int offset)
        {
            if (!IsTargetsFile && !IsPropsFile && valueDescriptor is IHasDefaultValue hasDefault)
            {
                if (hasDefault.DefaultValue != null && string.Equals(hasDefault.DefaultValue, value, StringComparison.OrdinalIgnoreCase))
                {
                    Document.Diagnostics.Add(
                        CoreDiagnostics.HasDefaultValue, attribute?.Span ?? element.OuterSpan,
                        ImmutableDictionary <string, object> .Empty.Add("Info", valueDescriptor),
                        DescriptionFormatter.GetKindNoun(valueDescriptor), valueDescriptor.Name, hasDefault.DefaultValue);
                }
            }


            if (valueDescriptor is IDeprecatable deprecatable)
            {
                CheckDeprecated(deprecatable, (INamedXObject)attribute ?? element);
            }

            // we skip calling base, and instead parse the expression with more options enabled
            // so that we can warn if the user is doing something likely invalid
            var kind    = MSBuildCompletionExtensions.InferValueKindIfUnknown(valueDescriptor);
            var options = kind.GetExpressionOptions() | ExpressionOptions.ItemsMetadataAndLists;

            var node = ExpressionParser.Parse(value, options, offset);

            VisitValueExpression(element, attribute, resolvedElement, resolvedAttribute, valueDescriptor, kind, node);
        }
Esempio n. 2
0
            protected override void VisitValueExpression(
                XElement element, XAttribute attribute, MSBuildElementSyntax resolvedElement, MSBuildAttributeSyntax resolvedAttribute,
                ITypedSymbol valueType, MSBuildValueKind kind, ExpressionNode node)
            {
                switch (kind.GetScalarType())
                {
                case MSBuildValueKind.TargetName:
                    foreach (var n in node.WithAllDescendants())
                    {
                        if (n is ExpressionText lit && lit.IsPure)
                        {
                            Navigations.Add(new MSBuildNavigationResult(
                                                MSBuildReferenceKind.Target, lit.Value, lit.Offset, lit.Length
                                                ));
                        }
                    }
                    break;

                case MSBuildValueKind.File:
                case MSBuildValueKind.FileOrFolder:
                case MSBuildValueKind.ProjectFile:
                case MSBuildValueKind.TaskAssemblyFile:
                case MSBuildValueKind.Unknown:
                    if (node is ListExpression list)
                    {
                        foreach (var n in list.Nodes)
                        {
                            var p = GetPathFromNode(n, (MSBuildRootDocument)Document);
                            if (p != null)
                            {
                                Navigations.Add(p);
                            }
                        }
                    }
                    var path = GetPathFromNode(node, (MSBuildRootDocument)Document);
                    if (path != null)
                    {
                        Navigations.Add(path);
                    }
                    break;
                }
            }
        public static List <string> GetTypeDescription(this ITypedSymbol info)
        {
            var kind = MSBuildCompletionExtensions.InferValueKindIfUnknown(info);

            var modifierList = GetTypeDescription(kind, info.CustomType);

            if (info.CustomType != null && info.CustomType.Values.Count > 0)
            {
                modifierList [0] = "enum";
            }

            if (info is PropertyInfo pi && pi.Reserved)
            {
                modifierList.Add("reserved");
            }
            if (info is MetadataInfo mi)
            {
                if (mi.Reserved)
                {
                    modifierList.Add("reserved");
                }
                if (mi.Required)
                {
                    modifierList.Add("required");
                }
            }

            if (info is TaskParameterInfo tpi)
            {
                if (tpi.IsOutput)
                {
                    modifierList.Add("output");
                }
                if (tpi.IsRequired)
                {
                    modifierList.Add("required");
                }
            }

            return(modifierList);
        }
        protected virtual void VisitValue(
            XElement element, XAttribute attribute,
            MSBuildElementSyntax resolvedElement, MSBuildAttributeSyntax resolvedAttribute,
            ITypedSymbol valueDescriptor, string value, int offset)
        {
            var kind = MSBuildCompletionExtensions.InferValueKindIfUnknown(valueDescriptor);

            if (!kind.AllowExpressions())
            {
                VisitValueExpression(
                    element, attribute, resolvedElement, resolvedAttribute,
                    valueDescriptor, kind, new ExpressionText(offset, value, true));
                return;
            }

            var expression =
                valueDescriptor?.ValueKind == MSBuildValueKind.Condition
                                        ? ExpressionParser.ParseCondition(value, offset)
                                        : ExpressionParser.Parse(value, kind.GetExpressionOptions(), offset);

            VisitValueExpression(
                element, attribute, resolvedElement, resolvedAttribute,
                valueDescriptor, kind, expression);
        }
Esempio n. 5
0
            void VisitPureLiteral(XElement element, ITypedSymbol valueDescriptor, MSBuildValueKind inferredKind, ExpressionText node)
            {
                string value = node.GetUnescapedValue();

                rr.ReferenceOffset = node.Offset;
                rr.ReferenceLength = node.Value.Length;
                rr.Reference       = value;

                switch (inferredKind)
                {
                case MSBuildValueKind.TaskOutputParameterName:
                    rr.ReferenceKind = MSBuildReferenceKind.TaskParameter;
                    return;

                case MSBuildValueKind.TargetName:
                    rr.ReferenceKind = MSBuildReferenceKind.Target;
                    return;

                case MSBuildValueKind.NuGetID:
                    rr.ReferenceKind = MSBuildReferenceKind.NuGetID;
                    return;

                case MSBuildValueKind.PropertyName:
                    rr.ReferenceKind = MSBuildReferenceKind.Property;
                    return;

                case MSBuildValueKind.ItemName:
                    rr.ReferenceKind = MSBuildReferenceKind.Item;
                    return;

                case MSBuildValueKind.TaskName:
                    rr.ReferenceKind = MSBuildReferenceKind.Task;
                    return;

                case MSBuildValueKind.TargetFramework:
                    rr.ReferenceKind = MSBuildReferenceKind.TargetFramework;
                    return;

                case MSBuildValueKind.TargetFrameworkIdentifier:
                    rr.ReferenceKind = MSBuildReferenceKind.TargetFrameworkIdentifier;
                    return;

                case MSBuildValueKind.TargetFrameworkVersion:
                    rr.ReferenceKind = MSBuildReferenceKind.TargetFrameworkVersion;
                    return;

                case MSBuildValueKind.TargetFrameworkProfile:
                    rr.ReferenceKind = MSBuildReferenceKind.TargetFrameworkProfile;
                    return;

                case MSBuildValueKind.MetadataName:
                    //this is used for KeepMetadata/RemoveMetadata.
                    //reasonable to resolve from first item in include.
                    var itemName = MSBuildMetadataReferenceCollector.GetIncludeExpression(element)
                                   .WithAllDescendants()
                                   .OfType <ExpressionItemName> ()
                                   .FirstOrDefault();
                    if (itemName != null)
                    {
                        rr.Reference     = (itemName.Name, value);
                        rr.ReferenceKind = MSBuildReferenceKind.Metadata;
                    }
                    return;
                }

                var knownVals = (IReadOnlyList <ISymbol>)valueDescriptor.CustomType?.Values ?? inferredKind.GetSimpleValues(true);

                if (knownVals != null && knownVals.Count != 0)
                {
                    foreach (var kv in knownVals)
                    {
                        if (string.Equals(kv.Name, value, StringComparison.OrdinalIgnoreCase))
                        {
                            rr.ReferenceKind = MSBuildReferenceKind.KnownValue;
                            rr.Reference     = kv;
                            return;
                        }
                    }
                }
            }
Esempio n. 6
0
            protected override void VisitValueExpression(
                XElement element, XAttribute attribute,
                MSBuildElementSyntax resolvedElement, MSBuildAttributeSyntax resolvedAttribute,
                ITypedSymbol valueDescriptor, MSBuildValueKind inferredKind, ExpressionNode node)
            {
                var nodeAtOffset = node.Find(offset);

                switch (nodeAtOffset)
                {
                case ExpressionItemName ei:
                    rr.ReferenceKind   = MSBuildReferenceKind.Item;
                    rr.ReferenceOffset = ei.Offset;
                    rr.ReferenceLength = ei.Name.Length;
                    rr.Reference       = ei.Name;
                    break;

                case ExpressionPropertyName propName:
                    rr.ReferenceKind   = MSBuildReferenceKind.Property;
                    rr.ReferenceOffset = propName.Offset;
                    rr.Reference       = propName.Name;
                    rr.ReferenceLength = propName.Length;
                    break;

                case ExpressionMetadata em:
                    if (em.ItemName == null || offset >= em.MetadataNameOffset)
                    {
                        rr.ReferenceKind   = MSBuildReferenceKind.Metadata;
                        rr.ReferenceOffset = em.MetadataNameOffset;
                        rr.Reference       = (em.GetItemName(), em.MetadataName);
                        rr.ReferenceLength = em.MetadataName.Length;
                    }
                    else
                    {
                        rr.ReferenceKind   = MSBuildReferenceKind.Item;
                        rr.ReferenceOffset = em.ItemNameOffset;
                        rr.Reference       = em.ItemName;
                        rr.ReferenceLength = em.ItemName.Length;
                    }
                    break;

                case ExpressionFunctionName name:
                    rr.ReferenceOffset = name.Offset;
                    rr.ReferenceLength = name.Name.Length;
                    switch (name.Parent)
                    {
                    case ExpressionItemNode _:
                        rr.ReferenceKind = MSBuildReferenceKind.ItemFunction;
                        rr.Reference     = name.Name;
                        break;

                    case ExpressionPropertyFunctionInvocation prop: {
                        if (prop.Target is ExpressionClassReference classRef)
                        {
                            rr.ReferenceKind = MSBuildReferenceKind.StaticPropertyFunction;
                            rr.Reference     = (classRef.Name, name.Name);
                        }
                        else if (prop.Target is ExpressionPropertyNode propNode)
                        {
                            var type = functionTypeProvider?.ResolveType(propNode) ?? MSBuildValueKind.Unknown;
                            rr.ReferenceKind = MSBuildReferenceKind.PropertyFunction;
                            rr.Reference     = (type, name.Name);
                        }
                        break;
                    }

                    case ExpressionConditionFunction _:
                        rr.ReferenceKind = MSBuildReferenceKind.ConditionFunction;
                        rr.Reference     = name.Name;
                        break;
                    }
                    break;

                case ExpressionClassReference cr:
                    if (!string.IsNullOrEmpty(cr.Name))
                    {
                        if (cr.Parent is ExpressionArgumentList)
                        {
                            rr.ReferenceKind = MSBuildReferenceKind.Enum;
                        }
                        else if (cr.Parent is ExpressionPropertyFunctionInvocation)
                        {
                            rr.ReferenceKind = MSBuildReferenceKind.ClassName;
                        }
                        else
                        {
                            break;
                        }
                        rr.ReferenceOffset = cr.Offset;
                        rr.Reference       = cr.Name;
                        rr.ReferenceLength = cr.Length;
                    }
                    break;

                case ExpressionText lit:
                    inferredKind = inferredKind.GetScalarType();
                    if (lit.IsPure)
                    {
                        VisitPureLiteral(element, valueDescriptor, inferredKind, lit);
                        if (inferredKind == MSBuildValueKind.TaskOutputParameterName)
                        {
                            rr.ReferenceKind   = MSBuildReferenceKind.TaskParameter;
                            rr.ReferenceOffset = lit.Offset;
                            rr.ReferenceLength = lit.Value.Length;
                            rr.Reference       = (element.ParentElement.Name.Name, lit.Value);
                            break;
                        }
                    }
                    switch (inferredKind)
                    {
                    case MSBuildValueKind.File:
                    case MSBuildValueKind.FileOrFolder:
                    case MSBuildValueKind.ProjectFile:
                    case MSBuildValueKind.TaskAssemblyFile:
                        var pathNode = lit.Parent as ConcatExpression ?? (ExpressionNode)lit;
                        var path     = MSBuildNavigation.GetPathFromNode(pathNode, (MSBuildRootDocument)Document);
                        if (path != null)
                        {
                            rr.ReferenceKind   = MSBuildReferenceKind.FileOrFolder;
                            rr.ReferenceOffset = path.Offset;
                            rr.ReferenceLength = path.Length;
                            rr.Reference       = path.Paths;
                        }
                        break;
                    }
                    break;
                }
            }
        public static (MSBuildDiagnosticDescriptor, object[]) GetExpressionError(ExpressionError error, ITypedSymbol info)
        {
            (MSBuildDiagnosticDescriptor, object[]) Return(MSBuildDiagnosticDescriptor desc, params object[] args) => (desc, args);

            return(error.Kind switch
            {
                ExpressionErrorKind.MetadataDisallowed => Return(MetadataDisallowed, DescriptionFormatter.GetKindNoun(info), info.Name),
                ExpressionErrorKind.EmptyListEntry => Return(EmptyListValue),
                ExpressionErrorKind.ExpectingItemName => Return(ExpectingItemName),
                ExpressionErrorKind.ExpectingRightParen => Return(ExpectingChars1, ')'),
                ExpressionErrorKind.ExpectingRightParenOrPeriod => Return(ExpectingChars2, ')', '.'),
                ExpressionErrorKind.ExpectingPropertyName => Return(ExpectingPropertyName),
                ExpressionErrorKind.ExpectingMetadataName => Return(ExpectingMetadataName),
                ExpressionErrorKind.ExpectingMetadataOrItemName => Return(ExpectingMetadataOrItemName),
                ExpressionErrorKind.ExpectingRightAngleBracket => Return(ExpectingChars1, '>'),
                ExpressionErrorKind.ExpectingRightParenOrDash => Return(ExpectingChars2, ')', '-'),
                ExpressionErrorKind.ItemsDisallowed => Return(ItemsDisallowed, DescriptionFormatter.GetKindNoun(info), info.Name),
                ExpressionErrorKind.ExpectingMethodOrTransform => Return(ExpectingFunctionOrTransform),
                ExpressionErrorKind.ExpectingMethodName => Return(ExpectingFunctionName),
                ExpressionErrorKind.ExpectingLeftParen => Return(ExpectingChars1, '('),
                ExpressionErrorKind.ExpectingRightParenOrComma => Return(ExpectingChars2, ')', ','),
                ExpressionErrorKind.ExpectingRightParenOrValue => Return(ExpectingRightParenOrValue),
                ExpressionErrorKind.ExpectingValue => Return(ExpectingValue),
                ExpressionErrorKind.CouldNotParseNumber => Return(CouldNotParseNumber),
                ExpressionErrorKind.IncompleteValue => Return(IncompleteValue),
                ExpressionErrorKind.ExpectingBracketColonColon => Return(ExpectingChars1, "]::"),
                ExpressionErrorKind.ExpectingClassName => Return(ExpectingClassName),
                ExpressionErrorKind.ExpectingClassNameComponent => Return(IncompleteClassName),
                ExpressionErrorKind.IncompleteString => Return(IncompleteString),
                ExpressionErrorKind.IncompleteProperty => Return(IncompleteProperty),
                _ => throw new System.Exception($"Unhandled ExpressionErrorKind '{error.Kind}'")
            });
Esempio n. 8
0
        public static MSBuildValueKind InferValueKindIfUnknown(this ITypedSymbol variable)
        {
            if (variable.ValueKind != MSBuildValueKind.Unknown)
            {
                return(variable.ValueKind);
            }

            //assume known items are files
            if (variable.ValueKind == MSBuildValueKind.UnknownItem)
            {
                return(MSBuildValueKind.File);
            }

            if (variable.ValueKind == MSBuildValueKind.UnknownItem.List())
            {
                return(MSBuildValueKind.File.List());
            }

            if (variable is PropertyInfo || variable is MetadataInfo)
            {
                if (StartsWith("Enable") ||
                    StartsWith("Disable") ||
                    StartsWith("Require") ||
                    StartsWith("Use") ||
                    StartsWith("Allow") ||
                    EndsWith("Enabled") ||
                    EndsWith("Disabled") ||
                    EndsWith("Required"))
                {
                    return(MSBuildValueKind.Bool);
                }
                if (EndsWith("DependsOn"))
                {
                    return(MSBuildValueKind.TargetName.List());
                }
                if (EndsWith("Path"))
                {
                    return(MSBuildValueKind.FileOrFolder);
                }
                if (EndsWith("Paths"))
                {
                    return(MSBuildValueKind.FileOrFolder.List());
                }
                if (EndsWith("Directory") ||
                    EndsWith("Dir"))
                {
                    return(MSBuildValueKind.Folder);
                }
                if (EndsWith("File"))
                {
                    return(MSBuildValueKind.File);
                }
                if (EndsWith("FileName"))
                {
                    return(MSBuildValueKind.Filename);
                }
                if (EndsWith("Url"))
                {
                    return(MSBuildValueKind.Url);
                }
                if (EndsWith("Ext"))
                {
                    return(MSBuildValueKind.Extension);
                }
                if (EndsWith("Guid"))
                {
                    return(MSBuildValueKind.Guid);
                }
                if (EndsWith("Directories") || EndsWith("Dirs"))
                {
                    return(MSBuildValueKind.Folder.List());
                }
                if (EndsWith("Files"))
                {
                    return(MSBuildValueKind.File.List());
                }
            }

            //make sure these work even if the common targets schema isn't loaded
            if (variable is PropertyInfo prop)
            {
                switch (prop.Name.ToLowerInvariant())
                {
                case "configuration":
                    return(MSBuildValueKind.Configuration);

                case "platform":
                    return(MSBuildValueKind.Platform);
                }
            }

            return(MSBuildValueKind.Unknown);

            bool StartsWith(string prefix) => variable.Name.StartsWith(prefix, StringComparison.OrdinalIgnoreCase) &&
            variable.Name.Length > prefix.Length &&
            char.IsUpper(variable.Name[prefix.Length]);
            bool EndsWith(string suffix) => variable.Name.EndsWith(suffix, StringComparison.OrdinalIgnoreCase);
        }
        private void Resolve(ITypedSymbol typedSymbol)
        {
            Symbol symbol = (Symbol)typedSymbol;

            SymbolType symbolBuiltinType = symbol.BuiltinType;

            DeclarationNode typedSymbolNode = (DeclarationNode)symbol.Node;

            CustomTypeDeclarationNode customTypeDeclarationNode = (CustomTypeDeclarationNode)typedSymbolNode;

            if (symbolBuiltinType == SymbolType.Uninitialized) // if symbolBuiltinType isn't one of the simple builtin types
            {
                // TODO think of: differentiate NotAClassError and UnknownTypeNameError
                if (_symbolTable.ContainsKey(typedSymbol.TypeName))
                {
                    Symbol typeSymbol = _symbolTable[typedSymbol.TypeName];

                    if (typeSymbol is ClassSymbol)
                    {
                        typedSymbol.ComplexType = typeSymbol;
                        symbol.BuiltinType      = SymbolType.Instance;
                        symbolBuiltinType       = SymbolType.Instance;


                        DeclarationNode declarationNode = (DeclarationNode)typeSymbol.Node;
                        declarationNode.Usages.Add(customTypeDeclarationNode.TypeNameNode);
                    }
                    else
                    {
                        typedSymbolNode.Annotations.Add(new UnknownTypeNameError(customTypeDeclarationNode.TypeNameNode.Value, customTypeDeclarationNode.TypeNameNode.Location));
                        return;
                    }
                }
                else
                {
                    typedSymbolNode.Annotations.Add(new UnknownTypeNameError(customTypeDeclarationNode.TypeNameNode.Value, customTypeDeclarationNode.TypeNameNode.Location));
                    return;
                }
            }

            switch (typedSymbol)
            {
            case FunctionSymbol _:
                switch (symbolBuiltinType)
                {
                case SymbolType.Class:
                case SymbolType.Prototype:
                case SymbolType.Func:
                    symbol.BuiltinType = SymbolType.Uninitialized;
                    typedSymbolNode.Annotations.Add(new UnsupportedFunctionTypeError(customTypeDeclarationNode.TypeNameNode.Location));
                    return;
                }

                break;

            case IArraySymbol _:
                switch (symbolBuiltinType)
                {
                case SymbolType.Int:
                case SymbolType.String:
                case SymbolType.Func:
                case SymbolType.Float:         // very limited type
                    break;

                default:
                    symbol.BuiltinType = SymbolType.Uninitialized;
                    typedSymbolNode.Annotations.Add(new UnsupportedArrayTypeError(customTypeDeclarationNode.TypeNameNode.Location));
                    return;
                }
                break;

            case NestableSymbol _:
                switch (symbolBuiltinType)
                {
                case SymbolType.Class:
                case SymbolType.Prototype:
                case SymbolType.Void:
                    symbol.BuiltinType = SymbolType.Uninitialized;
                    typedSymbolNode.Annotations.Add(new UnsupportedTypeError(customTypeDeclarationNode.TypeNameNode.Location));
                    return;
                }
                break;
            }
        }
Esempio n. 10
0
        //note: the value is unescaped, so offsets within it are not valid
        void VisitPureLiteral(ITypedSymbol info, MSBuildValueKind kind, string value, int offset)
        {
            if (info.CustomType != null && info.CustomType.AllowUnknownValues)
            {
                return;
            }

            var knownVals = (IReadOnlyList <ISymbol>)info.CustomType?.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 AddErrorWithArgs(MSBuildDiagnosticDescriptor d, params object[] args) => Document.Diagnostics.Add(d, new TextSpan(offset, value.Length), args);
        }
Esempio n. 11
0
        protected override void VisitValueExpression(
            XElement element, XAttribute attribute,
            MSBuildElementSyntax resolvedElement, MSBuildAttributeSyntax resolvedAttribute,
            ITypedSymbol info, MSBuildValueKind kind, ExpressionNode node)
        {
            bool allowExpressions = kind.AllowExpressions();
            bool allowLists       = kind.AllowListsOrCommaLists();

            if (node is ListExpression list)
            {
                if (!allowLists)
                {
                    Document.Diagnostics.Add(
                        CoreDiagnostics.UnexpectedList,
                        new TextSpan(list.Nodes[0].End, list.End - list.Nodes[0].End),
                        ImmutableDictionary <string, object> .Empty.Add("Name", info.Name),
                        DescriptionFormatter.GetKindNoun(info),
                        info.Name);
                }
                if (!allowExpressions)
                {
                    var expr = list.Nodes.FirstOrDefault(n => !(n is ExpressionText));
                    if (expr != null)
                    {
                        AddExpressionWarning(expr);
                    }
                }
            }
            else if (node is ExpressionText lit)
            {
                VisitPureLiteral(info, kind, lit.GetUnescapedValue(), lit.Offset);
            }
            else
            {
                if (!allowExpressions)
                {
                    AddExpressionWarning(node);
                }
            }

            foreach (var n in node.WithAllDescendants())
            {
                switch (n)
                {
                case ExpressionError err:
                    var(desc, args) = CoreDiagnostics.GetExpressionError(err, info);
                    Document.Diagnostics.Add(desc, new TextSpan(err.Offset, Math.Max(1, err.Length)), args);
                    break;

                case ExpressionMetadata meta:
                    var metaItem = meta.GetItemName();
                    if (!string.IsNullOrEmpty(metaItem) && !IsMetadataUsed(metaItem, meta.MetadataName, ReferenceUsage.Write))
                    {
                        Document.Diagnostics.Add(
                            CoreDiagnostics.UnwrittenMetadata,
                            meta.Span,
                            ImmutableDictionary <string, object> .Empty
                            .Add("ItemName", metaItem)
                            .Add("Name", meta.MetadataName)
                            .Add("Spans", new [] { new TextSpan(meta.MetadataNameOffset, meta.MetadataName.Length) }),
                            metaItem, meta.MetadataName
                            );
                    }
                    break;

                case ExpressionPropertyName prop:
                    if (!IsPropertyUsed(prop.Name, ReferenceUsage.Write))
                    {
                        Document.Diagnostics.Add(
                            CoreDiagnostics.UnwrittenProperty,
                            prop.Span,
                            ImmutableDictionary <string, object> .Empty
                            .Add("Name", prop.Name)
                            .Add("Spans", new[] { new TextSpan(prop.Offset, prop.Length) }),
                            prop.Name
                            );
                    }
                    break;

                case ExpressionItemName item:
                    if (!IsItemUsed(item.Name, ReferenceUsage.Write))
                    {
                        Document.Diagnostics.Add(
                            CoreDiagnostics.UnwrittenItem,
                            item.Span,
                            ImmutableDictionary <string, object> .Empty
                            .Add("Name", item.Name)
                            .Add("Spans", new[] { new TextSpan(item.Offset, item.Length) }),
                            item.Name
                            );
                    }
                    //TODO: deprecation squiggles in expressions
                    break;
                }
            }

            void AddExpressionWarning(ExpressionNode n)
            => Document.Diagnostics.Add(CoreDiagnostics.UnexpectedExpression,
                                        new TextSpan(n.Offset, n.Length),
                                        DescriptionFormatter.GetKindNoun(info),
                                        info.Name);
        }
Esempio n. 12
0
 public AstSymbolExpr(ITypedSymbol sym) : base(sym.Location)
 {
     this.Symbol = sym;
     this.Type   = sym.Type;
 }
 protected virtual void VisitValueExpression(
     XElement element, XAttribute attribute,
     MSBuildElementSyntax resolvedElement, MSBuildAttributeSyntax resolvedAttribute,
     ITypedSymbol valueType, MSBuildValueKind inferredKind, ExpressionNode node)
 {
 }