Beispiel #1
0
        private static Possible <INugetPackage> ParseNugetPackageFrom(
            [CanBeNull] IObjectLiteralExpression packageExpression)
        {
            if (packageExpression == null)
            {
                return(new MalformedConfigurationFailure("An object literal with a NuGet package definition is expected"));
            }

            string id;

            packageExpression.TryExtractLiteralFromAssignmentPropertyInitializer(NaiveConfigurationParsingUtilities.IdFieldName, out id);

            string version;

            packageExpression.TryExtractLiteralFromAssignmentPropertyInitializer(NaiveConfigurationParsingUtilities.VersionFieldName, out version);

            string alias;

            packageExpression.TryExtractLiteralFromAssignmentPropertyInitializer(NaiveConfigurationParsingUtilities.AliasFieldName, out alias);

            return(new NugetPackage
            {
                Id = id,
                Alias = alias,
                Version = version,
            });
        }
Beispiel #2
0
        /// <summary>
        /// Do a naive interpretation of an object literal to get NuGet resolver settings
        /// </summary>
        public Possible <IResolverSettings> TryGetResolverSettings(
            IObjectLiteralExpression resolverConfigurationLiteral)
        {
            Contract.Requires(resolverConfigurationLiteral != null);
            var result = new NugetResolverSettings {
                Kind = KnownResolverKind.NugetResolverKind, Name = "Nuget resolver for a naive configuration provider"
            };

            return

                // Parse 'configuration' field
                (ParseConfigurationField(resolverConfigurationLiteral).Then(nugetConfiguration =>
            {
                result.Configuration = nugetConfiguration;

                // Parse 'respositories' field if it exists
                return ParseRepositoriesField(resolverConfigurationLiteral, result.Repositories).Then(repositories =>

                                                                                                      // Parse 'packages' field if it exists
                                                                                                      ParsePackagesField(resolverConfigurationLiteral, result.Packages).Then(packages =>

                                                                                                                                                                             // Parse 'doNotEnforceDependencyVersions' field if it exists
                                                                                                                                                                             ParseDoNotEnforceDependencyVersionsField(resolverConfigurationLiteral).Then(doNotEnforceDependencyVersions =>
                {
                    if (doNotEnforceDependencyVersions.HasValue)
                    {
                        result.DoNotEnforceDependencyVersions = doNotEnforceDependencyVersions.Value;
                    }

                    // The NugetResolverSettings have now been completely parsed
                    return new Possible <IResolverSettings>(result);
                })));
            }));
        }
Beispiel #3
0
        // Parse 'packages' field if it exists
        private static Possible <List <INugetPackage> > ParsePackagesField(IObjectLiteralExpression resolverConfigurationLiteral, List <INugetPackage> packages)
        {
            IExpression expression;

            if (resolverConfigurationLiteral.TryFindAssignmentPropertyInitializer(NaiveConfigurationParsingUtilities.PackagesFieldName, out expression))
            {
                if (expression.Kind != SyntaxKind.ArrayLiteralExpression)
                {
                    return(new MalformedConfigurationFailure(
                               I($"An array literal is expected for field '{NaiveConfigurationParsingUtilities.PackagesFieldName}', but it is of type {expression.Kind}")));
                }

                var packagesExpression = expression.Cast <IArrayLiteralExpression>();
                foreach (var packageExpression in packagesExpression.Elements)
                {
                    var maybePackage = ParseNugetPackageFrom(packageExpression.As <IObjectLiteralExpression>());
                    if (!maybePackage.Succeeded)
                    {
                        return(maybePackage.Failure);
                    }

                    packages.Add(maybePackage.Result);
                }
            }

            return(packages);
        }
Beispiel #4
0
        /// <summary>
        /// Validates <paramref name="sourceFile"/> to follow package configuration structure.
        /// </summary>
        public static bool ValidatePackageConfiguration(ISourceFile sourceFile, Logger logger, LoggingContext loggingContext)
        {
            if (sourceFile.Statements.Count < 1)
            {
                logger.ReportAtLeastSingleFunctionCallInPackageConfigurationFile(loggingContext, sourceFile.LocationForLogging(sourceFile));
                return(false);
            }

            var objectLiteralExpressions = new IObjectLiteralExpression[sourceFile.Statements.Count];

            bool hasErrors = false;

            for (int i = 0; i < sourceFile.Statements.Count; ++i)
            {
                var configurationStatement = sourceFile.Statements[i];
                if (!configurationStatement.IsPackageConfigurationDeclaration())
                {
                    logger.ReportUnknownStatementInPackageConfigurationFile(
                        loggingContext,
                        configurationStatement.LocationForLogging(sourceFile));
                    hasErrors = true;
                    continue;
                }

                var callExpression = configurationStatement.AsCallExpression();

                if (callExpression.Arguments.Count != 1)
                {
                    string message = I($"Package configuration should take 1 argument but got {callExpression.Arguments.Count}");
                    logger.ReportInvalidPackageConfigurationFileFormat(
                        loggingContext,
                        callExpression.LocationForLogging(sourceFile),
                        message);
                    hasErrors = true;
                    continue;
                }

                var objectLiteral = callExpression.Arguments[0].As <IObjectLiteralExpression>();
                if (objectLiteral == null)
                {
                    string message = I($"Package configuration should take object literal but got {callExpression.Arguments[0].Kind}");
                    logger.ReportInvalidPackageConfigurationFileFormat(
                        loggingContext,
                        callExpression.LocationForLogging(sourceFile),
                        message);
                    hasErrors = true;
                    continue;
                }

                objectLiteralExpressions[i] = objectLiteral;
            }

            return(hasErrors);
        }
Beispiel #5
0
        // Parse 'configuration' field
        private Possible <INugetConfiguration> ParseConfigurationField(IObjectLiteralExpression resolverConfigurationLiteral)
        {
            IExpression expression;

            if (!resolverConfigurationLiteral.TryFindAssignmentPropertyInitializer(NaiveConfigurationParsingUtilities.ConfigurationFieldName, out expression))
            {
                return
                    (new MalformedConfigurationFailure(
                         I($"Field '{NaiveConfigurationParsingUtilities.ConfigurationFieldName}' is not present.")));
            }

            return(ParseNugetConfigurationFrom(expression.As <IObjectLiteralExpression>()));
        }
        /// <summary>
        /// Return the literal initializer for a given property name in an object literal
        /// </summary>
        public static bool TryExtractLiteralFromAssignmentPropertyInitializer(
            this IObjectLiteralExpression objectLiteral,
            string propertyName,
            out string literal)
        {
            IExpression expression;

            if (TryFindAssignmentPropertyInitializer(objectLiteral, propertyName, out expression))
            {
                literal = expression.As <ILiteralExpression>()?.Text;
                return(literal != null);
            }

            literal = null;
            return(false);
        }
Beispiel #7
0
        /// <summary>
        /// Gets any properties that haven't yet been filled in for an object literal
        /// </summary>
        public static IEnumerable<ISymbol> GetRemainingPropertiesForObjectLiteral(IObjectLiteralExpression objectLiteralExpression, IEnumerable<IType> types, ITypeChecker typeChecker)
        {
            if (objectLiteralExpression?.Properties?.Elements == null)
            {
                return Enumerable.Empty<ISymbol>();
            }

            var propertiesThatAlreadyAreSet = new HashSet<string>(
                objectLiteralExpression.Properties.Elements
                    .Select(property => property.As<IPropertyAssignment>()?.Name?.Text)
                    .Where(name => name != null));

            var allPossibleSymbols = AutoCompleteHelpers.GetSymbolsFromTypes(typeChecker, types);
            Contract.Assert(allPossibleSymbols != null);

            return allPossibleSymbols.Where(symbol => !propertiesThatAlreadyAreSet.Contains(symbol.Name));
        }
Beispiel #8
0
        private static int FitsOnOneLine(IObjectLiteralExpression expression, int remainingSpace)
        {
            if (expression.Properties == null)
            {
                return(remainingSpace - 2);
            }

            if (expression.Properties.Length > 2)
            {
                // Objects of more than 3 members get their own line
                return(-1);
            }

            int space = remainingSpace;

            foreach (var objectElement in expression.Properties)
            {
                if (objectElement.Kind != SyntaxKind.PropertyAssignment)
                {
                    // Only properties would fit on one line
                    return(-1);
                }

                if (space != remainingSpace)
                {
                    space -= 2; // Separator
                }

                var property = objectElement as IPropertyAssignment;

                if (property == null)
                {
                    // anything but a property will cause wrapping.
                    return(-1);
                }

                space -= property.Name.Text.Length;
                space -= 2; // separator
                space  = FitsOnOneLine(property.Initializer, space);
            }

            space -= 2; // brackets

            return(space);
        }
Beispiel #9
0
        private Possible <INugetConfiguration> ParseNugetConfigurationFrom(
            [CanBeNull] IObjectLiteralExpression configurationExpression)
        {
            IExpression expression;

            if (configurationExpression == null)
            {
                return(new MalformedConfigurationFailure("An object literal with NuGet resolver-specific configuration is expected"));
            }

            var result = new NugetConfiguration();

            if (configurationExpression.TryFindAssignmentPropertyInitializer(NaiveConfigurationParsingUtilities.CredentialProvidersFieldName, out expression))
            {
                if (expression.Kind != SyntaxKind.ArrayLiteralExpression)
                {
                    return(new MalformedConfigurationFailure("An array literal is expected for NuGet credential providers"));
                }

                var credentialProviders = expression.Cast <IArrayLiteralExpression>();
                foreach (var element in credentialProviders.Elements)
                {
                    var elementResult = ParseNugetConfigurationFrom(element.As <IObjectLiteralExpression>());
                    if (!elementResult.Succeeded)
                    {
                        return(elementResult);
                    }

                    result.CredentialProviders.Add(elementResult.Result);
                }
            }

            if (configurationExpression.TryFindAssignmentPropertyInitializer(NaiveConfigurationParsingUtilities.ToolUrlFieldName, out expression))
            {
                // TODO: Consider validating that string is well-formed URL
                result.ToolUrl = expression.As <ILiteralExpression>()?.Text;
            }

            if (configurationExpression.TryFindAssignmentPropertyInitializer(NaiveConfigurationParsingUtilities.HashFieldName, out expression))
            {
                result.Hash = expression.As <ILiteralExpression>()?.Text;
            }

            return(result);
        }
        private static int CompareObjectLiteralExpression(IObjectLiteralExpression left, IObjectLiteralExpression right)
        {
            // Standard left,right and null checks
            if (left == null && right == null)
            {
                return(0);
            }
            if (left == null)
            {
                return(1);
            }
            if (right == null)
            {
                return(-1);
            }

            return(CompareNodeArrays(left.Properties, right.Properties, (l, r) => CompareNodeAsText(l, r)));
        }
        /// <summary>
        /// Extracts an object literal that was specified in a configuration function.
        /// </summary>
        public static bool TryExtractConfigurationLiteral(
            this ISourceFile sourceFile,
            out IObjectLiteralExpression literal, out string failureReason)
        {
            List <IObjectLiteralExpression> literals;

            if (!sourceFile.TryExtractLiterals(
                    functionName: Names.ConfigurationFunctionCall,
                    allowMultipleLiterals: false,
                    literals: out literals,
                    failureReason: out failureReason))
            {
                literal = null;
                return(false);
            }

            literal = literals.First();
            return(true);
        }
        /// <summary>
        /// Return the expression initializer for a given property name in an object literal
        /// </summary>
        public static bool TryFindAssignmentPropertyInitializer(
            this IObjectLiteralExpression objectLiteral,
            string propertyName,
            out IExpression expression)
        {
            foreach (var property in objectLiteral.Properties)
            {
                if (string.Equals(property.Name.Text, propertyName))
                {
                    var expressionAssignment = property.As <IPropertyAssignment>()?.Initializer;
                    if (expressionAssignment != null)
                    {
                        expression = expressionAssignment;
                        return(true);
                    }
                }
            }

            expression = null;
            return(false);
        }
Beispiel #13
0
        // Parse 'doNotEnforceDependencyVersions' field if it exists
        private static Possible <bool?> ParseDoNotEnforceDependencyVersionsField(IObjectLiteralExpression resolverConfigurationLiteral)
        {
            IExpression expression;

            if (resolverConfigurationLiteral.TryFindAssignmentPropertyInitializer(NaiveConfigurationParsingUtilities.DoNotEnforceDependencyVersionsFieldName, out expression))
            {
                switch (expression.Kind)
                {
                case SyntaxKind.TrueKeyword:
                    return(true);

                case SyntaxKind.FalseKeyword:
                    return(false);

                default:
                    return(new MalformedConfigurationFailure(
                               I($"Field '{NaiveConfigurationParsingUtilities.DoNotEnforceDependencyVersionsFieldName}' is supposed to be a boolean literal, but is of type {expression.Kind}.")));
                }
            }

            return((bool?)null);
        }
Beispiel #14
0
        // Parse 'respositories' field if it exists
        private static Possible <Dictionary <string, string> > ParseRepositoriesField(IObjectLiteralExpression resolverConfigurationLiteral, Dictionary <string, string> repositories)
        {
            Contract.Assert(repositories != null);

            IExpression expression;

            if (resolverConfigurationLiteral.TryFindAssignmentPropertyInitializer(NaiveConfigurationParsingUtilities.RepositoriesFieldName, out expression))
            {
                var repositoriesExpression = expression.As <IObjectLiteralExpression>();
                if (repositoriesExpression == null)
                {
                    return(new MalformedConfigurationFailure("An object literal with NuGet respositories definitions is expected"));
                }

                foreach (var property in repositoriesExpression.Properties)
                {
                    if (property.Kind != SyntaxKind.PropertyAssignment)
                    {
                        return(new MalformedConfigurationFailure(
                                   I($"Field '{NaiveConfigurationParsingUtilities.RepositoriesFieldName}' is supposed to contain property assignments only but property '{property.Name.Text}' is of type {property.Kind}.")));
                    }

                    var propertyInitializer = property.Cast <IPropertyAssignment>().Initializer;
                    if (propertyInitializer.Kind != SyntaxKind.StringLiteral)
                    {
                        return(new MalformedConfigurationFailure(
                                   I($"Field '{NaiveConfigurationParsingUtilities.RepositoriesFieldName}' is supposed to contain string literal property assignments only, but property '{property.Name.Text}' has initializer of type '{propertyInitializer.Kind}'.")));
                    }

                    repositories.Add(
                        property.Name.Text,
                        propertyInitializer.Cast <IStringLiteral>().Text);
                }
            }

            return(repositories);
        }
Beispiel #15
0
        private static QualifierSpaceDeclaration ExtractQualifierSpace(IObjectLiteralExpression objectLiteral, DiagnosticContext context, bool emitLogEvents)
        {
            QualifierSpaceDeclaration result = new QualifierSpaceDeclaration();
            bool hasErrors = false;

            foreach (var objectLiteralElement in objectLiteral.Properties)
            {
                switch (objectLiteralElement.Kind)
                {
                case TypeScript.Net.Types.SyntaxKind.PropertyAssignment:
                {
                    var propertyAssignment = objectLiteralElement.Cast <IPropertyAssignment>();
                    var initializer        = propertyAssignment.Initializer;
                    var valueSpace         = initializer.As <IArrayLiteralExpression>();
                    if (valueSpace == null || valueSpace.Elements.Count == 0)
                    {
                        if (emitLogEvents)
                        {
                            context.Logger.ReportQualifierSpacePossibleValuesMustBeNonEmptyArrayLiteral(
                                context.LoggingContext,
                                initializer.LocationForLogging(context.SourceFile));
                        }

                        hasErrors = true;
                    }
                    else
                    {
                        var values = ExtractQualifierSpaceValues(valueSpace, context, emitLogEvents);
                        if (values == null)
                        {
                            hasErrors = true;
                        }
                        else
                        {
                            var text = propertyAssignment.Name.Text;
                            if (!QualifierTable.IsValidQualifierKey(text))
                            {
                                if (emitLogEvents)
                                {
                                    context.Logger.ReportQualifierSpaceValueMustBeValidKey(context.LoggingContext, propertyAssignment.LocationForLogging(context.SourceFile), text);
                                }

                                hasErrors = true;
                            }
                            else
                            {
                                result.Add(propertyAssignment.Name.Text, values);
                            }
                        }
                    }

                    break;
                }

                case TypeScript.Net.Types.SyntaxKind.ShorthandPropertyAssignment:
                {
                    if (emitLogEvents)
                    {
                        context.Logger.ReportQualifierSpacePropertyCannotBeInShorthand(
                            context.LoggingContext,
                            objectLiteralElement.LocationForLogging(context.SourceFile));
                    }

                    hasErrors = true;
                    break;
                }
                }
            }

            return(hasErrors ? null : result);
        }