public static IEnumerable<string> GetPatternsCollection(JsonObject rawProject, string projectDirectory, string projectFilePath, string propertyName, IEnumerable<string> defaultPatterns = null) { defaultPatterns = defaultPatterns ?? Enumerable.Empty<string>(); try { if (!rawProject.Keys.Contains(propertyName)) { return CreateCollection(projectDirectory, defaultPatterns.ToArray()); } var valueInString = rawProject.ValueAsString(propertyName); if (valueInString != null) { return CreateCollection(projectDirectory, valueInString); } var valuesInArray = rawProject.ValueAsStringArray(propertyName); if (valuesInArray != null) { return CreateCollection(projectDirectory, valuesInArray.Select(s => s.ToString()).ToArray()); } } catch (Exception ex) { throw FileFormatException.Create(ex, rawProject.Value(propertyName), projectFilePath); } throw FileFormatException.Create("Value must be either string or array.", rawProject.Value(propertyName), projectFilePath); }
private static List<CompilationMessage> ValueAsCompilationMessages(JsonObject obj, string key) { var messages = new List<CompilationMessage>(); var arrayValue = obj.Value(key) as JsonArray; for (int i = 0; i < arrayValue.Length; i++) { var item = arrayValue[i] as JsonObject; var message = new CompilationMessage { Message = item.ValueAsString(nameof(ICompilationMessage.Message)), FormattedMessage = item.ValueAsString(nameof(ICompilationMessage.FormattedMessage)), SourceFilePath = item.ValueAsString(nameof(ICompilationMessage.SourceFilePath)), Severity = (CompilationMessageSeverity)item.ValueAsInt(nameof(ICompilationMessage.Severity)), StartColumn = item.ValueAsInt(nameof(ICompilationMessage.StartColumn)), StartLine = item.ValueAsInt(nameof(ICompilationMessage.StartLine)), EndColumn = item.ValueAsInt(nameof(ICompilationMessage.EndColumn)), EndLine = item.ValueAsInt(nameof(ICompilationMessage.EndLine)), }; messages.Add(message); } return messages; }
internal ProjectFilesCollection(JsonObject rawProject, string projectDirectory, string projectFilePath, ICollection<ICompilationMessage> warnings = null) { _projectDirectory = projectDirectory; _projectFilePath = projectFilePath; var excludeBuiltIns = PatternsCollectionHelper.GetPatternsCollection(rawProject, projectDirectory, projectFilePath, "excludeBuiltIn", DefaultBuiltInExcludePatterns); var excludePatterns = PatternsCollectionHelper.GetPatternsCollection(rawProject, projectDirectory, projectFilePath, "exclude") .Concat(excludeBuiltIns); var contentBuiltIns = PatternsCollectionHelper.GetPatternsCollection(rawProject, projectDirectory, projectFilePath, "contentBuiltIn", DefaultContentsBuiltInPatterns); var compileBuiltIns = PatternsCollectionHelper.GetPatternsCollection(rawProject, projectDirectory, projectFilePath, "compileBuiltIn", DefaultCompileBuiltInPatterns); var resourceBuiltIns = PatternsCollectionHelper.GetPatternsCollection(rawProject, projectDirectory, projectFilePath, "resourceBuiltIn", DefaultResourcesBuiltInPatterns); // TODO: The legacy names will be retired in the future. var legacyPublishExcludePatternName = "bundleExclude"; var legacyPublishExcludePatternToken = rawProject.ValueAsJsonObject(legacyPublishExcludePatternName); if (legacyPublishExcludePatternToken != null) { _publishExcludePatterns = PatternsCollectionHelper.GetPatternsCollection(rawProject, projectDirectory, projectFilePath, legacyPublishExcludePatternName, DefaultPublishExcludePatterns); if (warnings != null) { warnings.Add(new FileFormatMessage( string.Format("Property \"{0}\" is deprecated. It is replaced by \"{1}\".", legacyPublishExcludePatternName, "publishExclude"), projectFilePath, CompilationMessageSeverity.Warning, legacyPublishExcludePatternToken)); } } else { _publishExcludePatterns = PatternsCollectionHelper.GetPatternsCollection(rawProject, projectDirectory, projectFilePath, "publishExclude", DefaultPublishExcludePatterns); } _sharedPatternsGroup = PatternGroup.Build(rawProject, projectDirectory, projectFilePath, "shared", legacyName: null, warnings: warnings, fallbackIncluding: DefaultSharedPatterns, additionalExcluding: excludePatterns); _resourcePatternsGroup = PatternGroup.Build(rawProject, projectDirectory, projectFilePath, "resource", "resources", warnings: warnings, additionalIncluding: resourceBuiltIns, additionalExcluding: excludePatterns); _preprocessPatternsGroup = PatternGroup.Build(rawProject, projectDirectory, projectFilePath, "preprocess", legacyName: null, warnings: warnings, fallbackIncluding: DefaultPreprocessPatterns, additionalExcluding: excludePatterns) .ExcludeGroup(_sharedPatternsGroup) .ExcludeGroup(_resourcePatternsGroup); _compilePatternsGroup = PatternGroup.Build(rawProject, projectDirectory, projectFilePath, "compile", "code", warnings: warnings, additionalIncluding: compileBuiltIns, additionalExcluding: excludePatterns) .ExcludeGroup(_sharedPatternsGroup) .ExcludeGroup(_preprocessPatternsGroup) .ExcludeGroup(_resourcePatternsGroup); _contentPatternsGroup = PatternGroup.Build(rawProject, projectDirectory, projectFilePath, "content", "files", warnings: warnings, additionalIncluding: contentBuiltIns, additionalExcluding: excludePatterns.Concat(_publishExcludePatterns)) .ExcludeGroup(_compilePatternsGroup) .ExcludeGroup(_preprocessPatternsGroup) .ExcludeGroup(_sharedPatternsGroup) .ExcludeGroup(_resourcePatternsGroup); _namedResources = NamedResourceReader.ReadNamedResources(rawProject, projectFilePath); }
public static IDictionary<string, string> ReadNamedResources(JsonObject rawProject, string projectFilePath) { if (!rawProject.Keys.Contains("namedResource")) { return new Dictionary<string, string>(); } var namedResourceToken = rawProject.ValueAsJsonObject("namedResource"); if (namedResourceToken == null) { throw FileFormatException.Create("Value must be object.", rawProject.Value("namedResource"), projectFilePath); } var namedResources = new Dictionary<string, string>(); foreach (var namedResourceKey in namedResourceToken.Keys) { var resourcePath = namedResourceToken.ValueAsString(namedResourceKey); if (resourcePath == null) { throw FileFormatException.Create("Value must be string.", namedResourceToken.Value(namedResourceKey), projectFilePath); } if (resourcePath.Value.Contains("*")) { throw FileFormatException.Create("Value cannot contain wildcards.", resourcePath, projectFilePath); } var resourceFileFullPath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(projectFilePath), resourcePath)); if (namedResources.ContainsKey(namedResourceKey)) { throw FileFormatException.Create( string.Format("The named resource {0} already exists.", namedResourceKey), resourcePath, projectFilePath); } namedResources.Add( namedResourceKey, resourceFileFullPath); } return namedResources; }
internal static PatternGroup Build(JsonObject rawProject, string projectDirectory, string projectFilePath, string name, string legacyName, IEnumerable<string> fallbackIncluding = null, IEnumerable<string> additionalIncluding = null, IEnumerable<string> additionalExcluding = null, bool includePatternsOnly = false, ICollection<ICompilationMessage> warnings = null) { string includePropertyName = name; if (!rawProject.Keys.Contains(name) && legacyName != null && rawProject.Keys.Contains(legacyName)) { includePropertyName = legacyName; if (warnings != null) { warnings.Add(new FileFormatMessage( string.Format("Property \"{0}\" is deprecated. It is replaced by \"{1}\".", legacyName, name), projectFilePath, CompilationMessageSeverity.Warning, rawProject.Value(legacyName))); } } additionalIncluding = additionalIncluding ?? Enumerable.Empty<string>(); var includePatterns = PatternsCollectionHelper.GetPatternsCollection(rawProject, projectDirectory, projectFilePath, includePropertyName, defaultPatterns: fallbackIncluding) .Concat(additionalIncluding) .Distinct(); if (includePatternsOnly) { return new PatternGroup(includePatterns); } additionalExcluding = additionalExcluding ?? Enumerable.Empty<string>(); var excludePatterns = PatternsCollectionHelper.GetPatternsCollection(rawProject, projectDirectory, projectFilePath, propertyName: name + "Exclude") .Concat(additionalExcluding) .Distinct(); var includeLiterals = PatternsCollectionHelper.GetPatternsCollection(rawProject, projectDirectory, projectFilePath, propertyName: name + "Files") .Distinct(); return new PatternGroup(includePatterns, excludePatterns, includeLiterals); }
private void BuildTargetFrameworksAndConfigurations(JsonObject projectJsonObject, ICollection<ICompilationMessage> diagnostics) { // Get the shared compilationOptions _defaultCompilerOptions = GetCompilationOptions(projectJsonObject) ?? new CompilerOptions(); _defaultTargetFrameworkConfiguration = new TargetFrameworkInformation { Dependencies = new List<LibraryDependency>() }; // Add default configurations _configurations["Debug"] = new CompilerOptions { Defines = new[] { "DEBUG", "TRACE" }, Optimize = false }; _configurations["Release"] = new CompilerOptions { Defines = new[] { "RELEASE", "TRACE" }, Optimize = true }; // The configuration node has things like debug/release compiler settings /* { "configurations": { "Debug": { }, "Release": { } } } */ var configurations = projectJsonObject.ValueAsJsonObject("configurations"); if (configurations != null) { foreach (var configKey in configurations.Keys) { var compilerOptions = GetCompilationOptions(configurations.ValueAsJsonObject(configKey)); // Only use this as a configuration if it's not a target framework _configurations[configKey] = compilerOptions; } } // The frameworks node is where target frameworks go /* { "frameworks": { "net45": { }, "k10": { } } } */ var frameworks = projectJsonObject.ValueAsJsonObject("frameworks"); if (frameworks != null) { foreach (var frameworkKey in frameworks.Keys) { try { var frameworkToken = frameworks.ValueAsJsonObject(frameworkKey); var success = BuildTargetFrameworkNode(frameworkKey, frameworkToken); if (!success) { diagnostics?.Add( new FileFormatMessage( $"\"{frameworkKey}\" is an unsupported framework", ProjectFilePath, CompilationMessageSeverity.Error, frameworkToken)); } } catch (Exception ex) { throw FileFormatException.Create(ex, frameworks.Value(frameworkKey), ProjectFilePath); } } } }
/// <summary> /// Parse a Json object which represents project configuration for a specified framework /// </summary> /// <param name="frameworkKey">The name of the framework</param> /// <param name="frameworkValue">The Json object represent the settings</param> /// <returns>Returns true if it successes.</returns> private bool BuildTargetFrameworkNode(string frameworkKey, JsonObject frameworkValue) { // If no compilation options are provided then figure them out from the node var compilerOptions = GetCompilationOptions(frameworkValue) ?? new CompilerOptions(); var frameworkName = FrameworkNameHelper.ParseFrameworkName(frameworkKey); // If it's not unsupported then keep it if (frameworkName == VersionUtility.UnsupportedFrameworkName) { // REVIEW: Should we skip unsupported target frameworks return false; } // Add the target framework specific define var defines = new HashSet<string>(compilerOptions.Defines ?? Enumerable.Empty<string>()); var frameworkDefinition = Tuple.Create(frameworkKey, frameworkName); var frameworkDefine = FrameworkNameHelper.MakeDefaultTargetFrameworkDefine(frameworkDefinition); if (!string.IsNullOrEmpty(frameworkDefine)) { defines.Add(frameworkDefine); } compilerOptions.Defines = defines; var targetFrameworkInformation = new TargetFrameworkInformation { FrameworkName = frameworkName, Dependencies = new List<LibraryDependency>() }; var frameworkDependencies = new List<LibraryDependency>(); PopulateDependencies( ProjectFilePath, frameworkDependencies, frameworkValue, "dependencies", isGacOrFrameworkReference: false); var frameworkAssemblies = new List<LibraryDependency>(); PopulateDependencies( ProjectFilePath, frameworkAssemblies, frameworkValue, "frameworkAssemblies", isGacOrFrameworkReference: true); frameworkDependencies.AddRange(frameworkAssemblies); targetFrameworkInformation.Dependencies = frameworkDependencies; targetFrameworkInformation.WrappedProject = frameworkValue.ValueAsString("wrappedProject"); var binNode = frameworkValue.ValueAsJsonObject("bin"); if (binNode != null) { targetFrameworkInformation.AssemblyPath = binNode.ValueAsString("assembly"); targetFrameworkInformation.PdbPath = binNode.ValueAsString("pdb"); } _compilationOptions[frameworkName] = compilerOptions; _targetFrameworks[frameworkName] = targetFrameworkInformation; return true; }
private static bool TryGetStringEnumerable(JsonObject parent, string property, out IEnumerable<string> result) { var collection = new List<string>(); var valueInString = parent.ValueAsString(property); if (valueInString != null) { collection.Add(valueInString); } else { var valueInArray = parent.ValueAsStringArray(property); if (valueInArray != null) { collection.AddRange(valueInArray); } else { result = null; return false; } } result = collection.SelectMany(value => value.Split(new[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries)); return true; }
private static void PopulateDependencies( string projectPath, IList<LibraryDependency> results, JsonObject settings, string propertyName, bool isGacOrFrameworkReference) { var dependencies = settings.ValueAsJsonObject(propertyName); if (dependencies != null) { foreach (var dependencyKey in dependencies.Keys) { if (string.IsNullOrEmpty(dependencyKey)) { throw FileFormatException.Create( "Unable to resolve dependency ''.", dependencies.Value(dependencyKey), projectPath); } var dependencyValue = dependencies.Value(dependencyKey); var dependencyTypeValue = LibraryDependencyType.Default; JsonString dependencyVersionAsString = null; if (dependencyValue is JsonObject) { // "dependencies" : { "Name" : { "version": "1.0", "type": "build" } } var dependencyValueAsObject = (JsonObject)dependencyValue; dependencyVersionAsString = dependencyValueAsObject.ValueAsString("version"); IEnumerable<string> strings; if (TryGetStringEnumerable(dependencyValueAsObject, "type", out strings)) { dependencyTypeValue = LibraryDependencyType.Parse(strings); } } else if (dependencyValue is JsonString) { // "dependencies" : { "Name" : "1.0" } dependencyVersionAsString = (JsonString)dependencyValue; } else { throw FileFormatException.Create( string.Format("Invalid dependency version: {0}. The format is not recognizable.", dependencyKey), dependencyValue, projectPath); } SemanticVersionRange dependencyVersionRange = null; if (!string.IsNullOrEmpty(dependencyVersionAsString?.Value)) { try { dependencyVersionRange = VersionUtility.ParseVersionRange(dependencyVersionAsString.Value); } catch (Exception ex) { throw FileFormatException.Create( ex, dependencyValue, projectPath); } } results.Add(new LibraryDependency { LibraryRange = new LibraryRange(dependencyKey, isGacOrFrameworkReference) { VersionRange = dependencyVersionRange, FileName = projectPath, Line = dependencyValue.Line, Column = dependencyValue.Column }, Type = dependencyTypeValue }); } } }
private static CompilerOptions GetCompilationOptions(JsonObject rawObject) { var rawOptions = rawObject.ValueAsJsonObject("compilationOptions"); if (rawOptions == null) { return null; } return new CompilerOptions { Defines = rawOptions.ValueAsStringArray("define"), LanguageVersion = rawOptions.ValueAsString("languageVersion"), AllowUnsafe = rawOptions.ValueAsNullableBoolean("allowUnsafe"), Platform = rawOptions.ValueAsString("platform"), WarningsAsErrors = rawOptions.ValueAsNullableBoolean("warningsAsErrors"), Optimize = rawOptions.ValueAsNullableBoolean("optimize"), KeyFile = rawOptions.ValueAsString("keyFile"), DelaySign = rawOptions.ValueAsNullableBoolean("delaySign"), StrongName = rawOptions.ValueAsNullableBoolean("strongName") }; }