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, }); }
/// <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); }))); })); }
// 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); }
/// <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); }
// 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); }
/// <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)); }
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); }
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); }
// 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); }
// 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); }
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); }