refactor to use our JSON parser

This commit is contained in:
Andrew Stanton-Nurse 2015-10-15 15:09:37 -07:00
parent 6d3f07234a
commit c60cef1e9b
12 changed files with 298 additions and 534 deletions

View file

@ -1,7 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved. // Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Newtonsoft.Json; using Microsoft.Extensions.JsonParser.Sources;
namespace Microsoft.Extensions.ProjectModel namespace Microsoft.Extensions.ProjectModel
{ {
@ -14,20 +14,6 @@ namespace Microsoft.Extensions.ProjectModel
: this(errorCode, message, filePath, severity, startLine: 1, startColumn: 0) : this(errorCode, message, filePath, severity, startLine: 1, startColumn: 0)
{ } { }
public DiagnosticMessage(string errorCode, string message, string filePath, DiagnosticMessageSeverity severity, IJsonLineInfo token)
: this(
errorCode,
message,
$"{filePath}({token.LineNumber},{token.LinePosition}): {severity.ToString().ToLowerInvariant()} {errorCode}: {message}",
filePath,
severity,
token.LineNumber,
token.LinePosition,
endLine: token.LineNumber,
endColumn: token.LinePosition,
source: null)
{ }
public DiagnosticMessage(string errorCode, string message, string filePath, DiagnosticMessageSeverity severity, int startLine, int startColumn) public DiagnosticMessage(string errorCode, string message, string filePath, DiagnosticMessageSeverity severity, int startLine, int startColumn)
: this( : this(
errorCode, errorCode,

View file

@ -2,8 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using Newtonsoft.Json; using Microsoft.Extensions.JsonParser.Sources;
using Newtonsoft.Json.Linq;
namespace Microsoft.Extensions.ProjectModel namespace Microsoft.Extensions.ProjectModel
{ {
@ -30,11 +29,11 @@ namespace Microsoft.Extensions.ProjectModel
internal static FileFormatException Create(Exception exception, string filePath) internal static FileFormatException Create(Exception exception, string filePath)
{ {
if (exception is JsonReaderException) if (exception is JsonDeserializerException)
{ {
return new FileFormatException(exception.Message, exception) return new FileFormatException(exception.Message, exception)
.WithFilePath(filePath) .WithFilePath(filePath)
.WithLineInfo((JsonReaderException)exception); .WithLineInfo((JsonDeserializerException)exception);
} }
else else
{ {
@ -43,7 +42,7 @@ namespace Microsoft.Extensions.ProjectModel
} }
} }
internal static FileFormatException Create(Exception exception, JToken jsonValue, string filePath) internal static FileFormatException Create(Exception exception, JsonValue jsonValue, string filePath)
{ {
var result = Create(exception, jsonValue) var result = Create(exception, jsonValue)
.WithFilePath(filePath); .WithFilePath(filePath);
@ -51,7 +50,7 @@ namespace Microsoft.Extensions.ProjectModel
return result; return result;
} }
internal static FileFormatException Create(Exception exception, IJsonLineInfo jsonValue) internal static FileFormatException Create(Exception exception, JsonValue jsonValue)
{ {
var result = new FileFormatException(exception.Message, exception) var result = new FileFormatException(exception.Message, exception)
.WithLineInfo(jsonValue); .WithLineInfo(jsonValue);
@ -59,7 +58,7 @@ namespace Microsoft.Extensions.ProjectModel
return result; return result;
} }
internal static FileFormatException Create(string message, IJsonLineInfo jsonValue, string filePath) internal static FileFormatException Create(string message, JsonValue jsonValue, string filePath)
{ {
var result = Create(message, jsonValue) var result = Create(message, jsonValue)
.WithFilePath(filePath); .WithFilePath(filePath);
@ -75,7 +74,7 @@ namespace Microsoft.Extensions.ProjectModel
return result; return result;
} }
internal static FileFormatException Create(string message, IJsonLineInfo jsonValue) internal static FileFormatException Create(string message, JsonValue jsonValue)
{ {
var result = new FileFormatException(message) var result = new FileFormatException(message)
.WithLineInfo(jsonValue); .WithLineInfo(jsonValue);
@ -95,30 +94,30 @@ namespace Microsoft.Extensions.ProjectModel
return this; return this;
} }
private FileFormatException WithLineInfo(IJsonLineInfo value) private FileFormatException WithLineInfo(JsonValue value)
{ {
if (value == null) if (value == null)
{ {
throw new ArgumentNullException(nameof(value)); throw new ArgumentNullException(nameof(value));
} }
Line = value.LineNumber; Line = value.Line;
Column = value.LinePosition; Column = value.Column;
return this; return this;
} }
private FileFormatException WithLineInfo(JsonReaderException exception) private FileFormatException WithLineInfo(JsonDeserializerException exception)
{ {
if (exception == null) if (exception == null)
{ {
throw new ArgumentNullException(nameof(exception)); throw new ArgumentNullException(nameof(exception));
} }
Line = exception.LineNumber; Line = exception.Line;
Column = exception.LinePosition; Column = exception.Column;
return this; return this;
} }
} }
} }

View file

@ -4,13 +4,13 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using Newtonsoft.Json.Linq; using Microsoft.Extensions.JsonParser.Sources;
namespace Microsoft.Extensions.ProjectModel namespace Microsoft.Extensions.ProjectModel
{ {
public class GlobalSettings public class GlobalSettings
{ {
public const string GlobalFileName = "global.json"; public const string FileName = "global.json";
public IList<string> ProjectSearchPaths { get; private set; } public IList<string> ProjectSearchPaths { get; private set; }
public string PackagesPath { get; private set; } public string PackagesPath { get; private set; }
@ -28,7 +28,7 @@ namespace Microsoft.Extensions.ProjectModel
globalSettings = null; globalSettings = null;
string globalJsonPath = null; string globalJsonPath = null;
if (Path.GetFileName(path) == GlobalFileName) if (Path.GetFileName(path) == FileName)
{ {
globalJsonPath = path; globalJsonPath = path;
path = Path.GetDirectoryName(path); path = Path.GetDirectoryName(path);
@ -39,7 +39,7 @@ namespace Microsoft.Extensions.ProjectModel
} }
else else
{ {
globalJsonPath = Path.Combine(path, GlobalFileName); globalJsonPath = Path.Combine(path, FileName);
} }
globalSettings = new GlobalSettings(); globalSettings = new GlobalSettings();
@ -49,7 +49,7 @@ namespace Microsoft.Extensions.ProjectModel
using (var fs = File.OpenRead(globalJsonPath)) using (var fs = File.OpenRead(globalJsonPath))
{ {
var reader = new StreamReader(fs); var reader = new StreamReader(fs);
var jobject = JObject.Parse(reader.ReadToEnd()); var jobject = JsonDeserializer.Deserialize(reader) as JsonObject;
if (jobject == null) if (jobject == null)
{ {
@ -61,7 +61,7 @@ namespace Microsoft.Extensions.ProjectModel
new string[] { }; new string[] { };
globalSettings.ProjectSearchPaths = new List<string>(projectSearchPaths); globalSettings.ProjectSearchPaths = new List<string>(projectSearchPaths);
globalSettings.PackagesPath = jobject.Value<string>("packages"); globalSettings.PackagesPath = jobject.ValueAsString("packages");
globalSettings.FilePath = globalJsonPath; globalSettings.FilePath = globalJsonPath;
} }
} }
@ -75,7 +75,7 @@ namespace Microsoft.Extensions.ProjectModel
public static bool HasGlobalFile(string path) public static bool HasGlobalFile(string path)
{ {
string projectPath = Path.Combine(path, GlobalFileName); string projectPath = Path.Combine(path, FileName);
return File.Exists(projectPath); return File.Exists(projectPath);
} }

View file

@ -5,111 +5,92 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Microsoft.Extensions.JsonParser.Sources;
using Microsoft.Extensions.ProjectModel.Utilities; using Microsoft.Extensions.ProjectModel.Utilities;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NuGet.Frameworks; using NuGet.Frameworks;
using NuGet.Packaging;
using NuGet.Packaging.Core; using NuGet.Packaging.Core;
using NuGet.Versioning; using NuGet.Versioning;
namespace Microsoft.Extensions.ProjectModel.Graph namespace Microsoft.Extensions.ProjectModel.Graph
{ {
public static class LockFileReader internal static class LockFileReader
{ {
public static LockFile Read(string path) public static LockFile Read(string filePath)
{ {
using(var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)) using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return Read(fs);
}
}
public static LockFile Read(Stream stream)
{
using (var textReader = new StreamReader(stream))
{ {
try try
{ {
using (var jsonReader = new JsonTextReader(textReader)) return Read(stream);
{
while (jsonReader.TokenType != JsonToken.StartObject)
{
if (!jsonReader.Read())
{
throw new InvalidDataException();
}
}
var token = JToken.Load(jsonReader);
return ReadLockFile(token as JObject);
}
} }
catch catch (FileFormatException ex)
{ {
// Ran into parsing errors, mark it as unlocked and out-of-date throw ex.WithFilePath(filePath);
return new LockFile }
{ catch (Exception ex)
Version = int.MinValue {
}; throw FileFormatException.Create(ex, filePath);
} }
} }
} }
public static void Write(Stream stream, LockFile lockFile) internal static LockFile Read(Stream stream)
{ {
using (var textWriter = new StreamWriter(stream)) try
{ {
using (var jsonWriter = new JsonTextWriter(textWriter)) var reader = new StreamReader(stream);
{ var jobject = JsonDeserializer.Deserialize(reader) as JsonObject;
jsonWriter.Formatting = Formatting.Indented;
var json = WriteLockFile(lockFile); if (jobject != null)
json.WriteTo(jsonWriter); {
return ReadLockFile(jobject);
} }
else
{
throw new InvalidDataException();
}
}
catch
{
// Ran into parsing errors, mark it as unlocked and out-of-date
return new LockFile
{
Version = int.MinValue
};
} }
} }
private static LockFile ReadLockFile(JObject cursor) private static LockFile ReadLockFile(JsonObject cursor)
{ {
var lockFile = new LockFile(); var lockFile = new LockFile();
lockFile.Version = ReadInt(cursor, "version", defaultValue: int.MinValue); lockFile.Version = ReadInt(cursor, "version", defaultValue: int.MinValue);
lockFile.Targets = ReadObject(cursor["targets"] as JObject, ReadTarget); lockFile.Targets = ReadObject(cursor.ValueAsJsonObject("targets"), ReadTarget);
lockFile.ProjectFileDependencyGroups = ReadObject(cursor["projectFileDependencyGroups"] as JObject, ReadProjectFileDependencyGroup); lockFile.ProjectFileDependencyGroups = ReadObject(cursor.ValueAsJsonObject("projectFileDependencyGroups"), ReadProjectFileDependencyGroup);
ReadLibrary(cursor["libraries"] as JObject, lockFile); ReadLibrary(cursor.ValueAsJsonObject("libraries"), lockFile);
return lockFile; return lockFile;
} }
private static JObject WriteLockFile(LockFile lockFile) private static void ReadLibrary(JsonObject json, LockFile lockFile)
{
var json = new JObject();
json["locked"] = new JValue(false);
json["version"] = new JValue(LockFile.CurrentVersion);
json["targets"] = WriteObject(lockFile.Targets, WriteTarget);
json["libraries"] = WriteLibraries(lockFile);
json["projectFileDependencyGroups"] = WriteObject(lockFile.ProjectFileDependencyGroups, WriteProjectFileDependencyGroup);
return json;
}
private static void ReadLibrary(JObject json, LockFile lockFile)
{ {
if (json == null) if (json == null)
{ {
return; return;
} }
foreach (var property in json) foreach (var key in json.Keys)
{ {
var value = property.Value as JObject; var value = json.ValueAsJsonObject(key);
if (value == null) if (value == null)
{ {
continue; throw FileFormatException.Create("The value type is not object.", json.Value(key));
} }
var parts = property.Key.Split(new[] { '/' }, 2); var parts = key.Split(new[] { '/' }, 2);
var name = parts[0]; var name = parts[0];
var version = parts.Length == 2 ? NuGetVersion.Parse(parts[1]) : null; var version = parts.Length == 2 ? NuGetVersion.Parse(parts[1]) : null;
var type = value["type"]?.Value<string>(); var type = value.ValueAsString("type")?.Value;
if (type == null || type == "package") if (type == null || type == "package")
{ {
@ -118,8 +99,8 @@ namespace Microsoft.Extensions.ProjectModel.Graph
Name = name, Name = name,
Version = version, Version = version,
IsServiceable = ReadBool(value, "serviceable", defaultValue: false), IsServiceable = ReadBool(value, "serviceable", defaultValue: false),
Sha512 = ReadString(value["sha512"]), Sha512 = ReadString(value.Value("sha512")),
Files = ReadPathArray(value["files"] as JArray, ReadString) Files = ReadPathArray(value.Value("files"), ReadString)
}); });
} }
else if (type == "project") else if (type == "project")
@ -128,55 +109,20 @@ namespace Microsoft.Extensions.ProjectModel.Graph
{ {
Name = name, Name = name,
Version = version, Version = version,
Path = ReadString(value["path"]) Path = ReadString(value.Value("path"))
}); });
} }
} }
} }
private static JObject WriteLibraries(LockFile lockFile) private static LockFileTarget ReadTarget(string property, JsonValue json)
{ {
var result = new JObject(); var jobject = json as JsonObject;
if (jobject == null)
foreach (var library in lockFile.ProjectLibraries)
{ {
var value = new JObject(); throw FileFormatException.Create("The value type is not an object.", json);
value["type"] = WriteString("project");
value["path"] = WriteString(library.Path);
result[$"{library.Name}/{library.Version.ToString()}"] = value;
} }
foreach (var library in lockFile.PackageLibraries)
{
var value = new JObject();
value["type"] = WriteString("package");
if (library.IsServiceable)
{
WriteBool(value, "serviceable", library.IsServiceable);
}
value["sha512"] = WriteString(library.Sha512);
WritePathArray(value, "files", library.Files.OrderBy(f => f), WriteString);
result[$"{library.Name}/{library.Version.ToString()}"] = value;
}
return result;
}
private static JProperty WriteTarget(LockFileTarget target)
{
var json = WriteObject(target.Libraries, WriteTargetLibrary);
var key = target.TargetFramework + (target.RuntimeIdentifier == null ? "" : "/" + target.RuntimeIdentifier);
return new JProperty(key, json);
}
private static LockFileTarget ReadTarget(string property, JToken json)
{
var target = new LockFileTarget(); var target = new LockFileTarget();
var parts = property.Split(new[] { '/' }, 2); var parts = property.Split(new[] { '/' }, 2);
target.TargetFramework = NuGetFramework.Parse(parts[0]); target.TargetFramework = NuGetFramework.Parse(parts[0]);
@ -185,13 +131,19 @@ namespace Microsoft.Extensions.ProjectModel.Graph
target.RuntimeIdentifier = parts[1]; target.RuntimeIdentifier = parts[1];
} }
target.Libraries = ReadObject(json as JObject, ReadTargetLibrary); target.Libraries = ReadObject(jobject, ReadTargetLibrary);
return target; return target;
} }
private static LockFileTargetLibrary ReadTargetLibrary(string property, JToken json) private static LockFileTargetLibrary ReadTargetLibrary(string property, JsonValue json)
{ {
var jobject = json as JsonObject;
if (jobject == null)
{
throw FileFormatException.Create("The value type is not an object.", json);
}
var library = new LockFileTargetLibrary(); var library = new LockFileTargetLibrary();
var parts = property.Split(new[] { '/' }, 2); var parts = property.Split(new[] { '/' }, 2);
@ -201,291 +153,143 @@ namespace Microsoft.Extensions.ProjectModel.Graph
library.Version = NuGetVersion.Parse(parts[1]); library.Version = NuGetVersion.Parse(parts[1]);
} }
var type = json["type"]; library.Type = jobject.ValueAsString("type");
if (type != null) var framework = jobject.ValueAsString("framework");
{
library.Type = ReadString(type);
}
var framework = json["framework"];
if (framework != null) if (framework != null)
{ {
library.TargetFramework = NuGetFramework.Parse(ReadString(framework)); library.TargetFramework = NuGetFramework.Parse(framework);
} }
library.Dependencies = ReadObject(json["dependencies"] as JObject, ReadPackageDependency); library.Dependencies = ReadObject(jobject.ValueAsJsonObject("dependencies"), ReadPackageDependency);
library.FrameworkAssemblies = new HashSet<string>(ReadArray(json["frameworkAssemblies"] as JArray, ReadFrameworkAssemblyReference), StringComparer.OrdinalIgnoreCase); library.FrameworkAssemblies = new HashSet<string>(ReadArray(jobject.Value("frameworkAssemblies"), ReadFrameworkAssemblyReference), StringComparer.OrdinalIgnoreCase);
library.RuntimeAssemblies = ReadObject(json["runtime"] as JObject, ReadFileItem); library.RuntimeAssemblies = ReadObject(jobject.ValueAsJsonObject("runtime"), ReadFileItem);
library.CompileTimeAssemblies = ReadObject(json["compile"] as JObject, ReadFileItem); library.CompileTimeAssemblies = ReadObject(jobject.ValueAsJsonObject("compile"), ReadFileItem);
library.ResourceAssemblies = ReadObject(json["resource"] as JObject, ReadFileItem); library.ResourceAssemblies = ReadObject(jobject.ValueAsJsonObject("resource"), ReadFileItem);
library.NativeLibraries = ReadObject(json["native"] as JObject, ReadFileItem); library.NativeLibraries = ReadObject(jobject.ValueAsJsonObject("native"), ReadFileItem);
return library; return library;
} }
private static JProperty WriteTargetLibrary(LockFileTargetLibrary library) private static ProjectFileDependencyGroup ReadProjectFileDependencyGroup(string property, JsonValue json)
{
var json = new JObject();
json["type"] = WriteString(library.Type);
if (library.TargetFramework != null)
{
json["framework"] = WriteString(library.TargetFramework.ToString());
}
if (library.Dependencies.Count > 0)
{
json["dependencies"] = WriteObject(library.Dependencies.OrderBy(p => p.Id), WritePackageDependency);
}
if (library.FrameworkAssemblies.Count > 0)
{
json["frameworkAssemblies"] = WriteArray(library.FrameworkAssemblies.OrderBy(f => f), WriteFrameworkAssemblyReference);
}
if (library.CompileTimeAssemblies.Count > 0)
{
json["compile"] = WriteObject(library.CompileTimeAssemblies, WriteFileItem);
}
if (library.RuntimeAssemblies.Count > 0)
{
json["runtime"] = WriteObject(library.RuntimeAssemblies, WriteFileItem);
}
if (library.ResourceAssemblies.Count > 0)
{
json["resource"] = WriteObject(library.ResourceAssemblies, WriteFileItem);
}
if (library.NativeLibraries.Count > 0)
{
json["native"] = WriteObject(library.NativeLibraries, WriteFileItem);
}
return new JProperty(library.Name + "/" + library.Version, json);
}
private static ProjectFileDependencyGroup ReadProjectFileDependencyGroup(string property, JToken json)
{ {
return new ProjectFileDependencyGroup( return new ProjectFileDependencyGroup(
NuGetFramework.Parse(property), NuGetFramework.Parse(property),
ReadArray(json as JArray, ReadString)); ReadArray(json, ReadString));
} }
private static JProperty WriteProjectFileDependencyGroup(ProjectFileDependencyGroup frameworkInfo) private static PackageDependency ReadPackageDependency(string property, JsonValue json)
{ {
return new JProperty( var versionStr = ReadString(json);
frameworkInfo.FrameworkName?.DotNetFrameworkName ?? string.Empty,
WriteArray(frameworkInfo.Dependencies, WriteString));
}
private static PackageDependencyGroup ReadPackageDependencySet(string property, JToken json)
{
var targetFramework = string.Equals(property, "*") ? null : NuGetFramework.Parse(property);
return new PackageDependencyGroup(
targetFramework,
ReadObject(json as JObject, ReadPackageDependency));
}
private static JProperty WritePackageDependencySet(PackageDependencyGroup item)
{
return new JProperty(
item.TargetFramework?.ToString() ?? "*",
WriteObject(item.Packages, WritePackageDependency));
}
private static PackageDependency ReadPackageDependency(string property, JToken json)
{
var versionStr = json.Value<string>();
return new PackageDependency( return new PackageDependency(
property, property,
versionStr == null ? null : VersionRange.Parse(versionStr)); versionStr == null ? null : VersionRange.Parse(versionStr));
} }
private static JProperty WritePackageDependency(PackageDependency item) private static LockFileItem ReadFileItem(string property, JsonValue json)
{
return new JProperty(
item.Id,
WriteString(item.VersionRange?.ToString()));
}
private static LockFileItem ReadFileItem(string property, JToken json)
{ {
var item = new LockFileItem { Path = PathUtility.GetPathWithDirectorySeparator(property) }; var item = new LockFileItem { Path = PathUtility.GetPathWithDirectorySeparator(property) };
foreach (var subProperty in json.OfType<JProperty>()) var jobject = json as JsonObject;
if (jobject != null)
{ {
item.Properties[subProperty.Name] = subProperty.Value.Value<string>(); foreach (var subProperty in jobject.Keys)
{
item.Properties[subProperty] = jobject.ValueAsString(subProperty);
}
} }
return item; return item;
} }
private static JProperty WriteFileItem(LockFileItem item) private static string ReadFrameworkAssemblyReference(JsonValue json)
{ {
return new JProperty( return ReadString(json);
item.Path,
new JObject(item.Properties.Select(x => new JProperty(x.Key, x.Value))));
} }
private static string ReadFrameworkAssemblyReference(JToken json) private static IList<TItem> ReadArray<TItem>(JsonValue json, Func<JsonValue, TItem> readItem)
{
return json.Value<string>();
}
private static JToken WriteFrameworkAssemblyReference(string item)
{
return new JValue(item);
}
private static FrameworkSpecificGroup ReadPackageReferenceSet(JToken json)
{
var frameworkName = json["targetFramework"]?.ToString();
return new FrameworkSpecificGroup(
string.IsNullOrEmpty(frameworkName) ? null : NuGetFramework.Parse(frameworkName),
ReadArray(json["references"] as JArray, ReadString));
}
private static JToken WritePackageReferenceSet(FrameworkSpecificGroup item)
{
var json = new JObject();
json["targetFramework"] = item.TargetFramework?.ToString();
json["references"] = WriteArray(item.Items, WriteString);
return json;
}
private static IList<TItem> ReadArray<TItem>(JArray json, Func<JToken, TItem> readItem)
{ {
if (json == null) if (json == null)
{ {
return new List<TItem>(); return new List<TItem>();
} }
var items = new List<TItem>();
foreach (var child in json) var jarray = json as JsonArray;
if (jarray == null)
{ {
items.Add(readItem(child)); throw FileFormatException.Create("The value type is not array.", json);
}
var items = new List<TItem>();
for (int i = 0; i < jarray.Length; ++i)
{
items.Add(readItem(jarray[i]));
} }
return items; return items;
} }
private static IList<string> ReadPathArray(JArray json, Func<JToken, string> readItem) private static IList<string> ReadPathArray(JsonValue json, Func<JsonValue, string> readItem)
{ {
return ReadArray(json, readItem).Select(f => PathUtility.GetPathWithDirectorySeparator(f)).ToList(); return ReadArray(json, readItem).Select(f => PathUtility.GetPathWithDirectorySeparator(f)).ToList();
} }
private static void WriteArray<TItem>(JToken json, string property, IEnumerable<TItem> items, Func<TItem, JToken> writeItem) private static IList<TItem> ReadObject<TItem>(JsonObject json, Func<string, JsonValue, TItem> readItem)
{
if (items.Any())
{
json[property] = WriteArray(items, writeItem);
}
}
private static void WritePathArray(JToken json, string property, IEnumerable<string> items, Func<string, JToken> writeItem)
{
WriteArray(json, property, items.Select(f => PathUtility.GetPathWithForwardSlashes(f)), writeItem);
}
private static JArray WriteArray<TItem>(IEnumerable<TItem> items, Func<TItem, JToken> writeItem)
{
var array = new JArray();
foreach (var item in items)
{
array.Add(writeItem(item));
}
return array;
}
private static JArray WritePathArray(IEnumerable<string> items, Func<string, JToken> writeItem)
{
return WriteArray(items.Select(f => PathUtility.GetPathWithForwardSlashes(f)), writeItem);
}
private static IList<TItem> ReadObject<TItem>(JObject json, Func<string, JToken, TItem> readItem)
{ {
if (json == null) if (json == null)
{ {
return new List<TItem>(); return new List<TItem>();
} }
var items = new List<TItem>(); var items = new List<TItem>();
foreach (var child in json) foreach (var childKey in json.Keys)
{ {
items.Add(readItem(child.Key, child.Value)); items.Add(readItem(childKey, json.Value(childKey)));
} }
return items; return items;
} }
private static void WriteObject<TItem>(JToken json, string property, IEnumerable<TItem> items, Func<TItem, JProperty> writeItem) private static bool ReadBool(JsonObject cursor, string property, bool defaultValue)
{ {
if (items.Any()) var valueToken = cursor.Value(property) as JsonBoolean;
{
json[property] = WriteObject(items, writeItem);
}
}
private static JObject WriteObject<TItem>(IEnumerable<TItem> items, Func<TItem, JProperty> writeItem)
{
var array = new JObject();
foreach (var item in items)
{
array.Add(writeItem(item));
}
return array;
}
private static bool ReadBool(JToken cursor, string property, bool defaultValue)
{
var valueToken = cursor[property];
if (valueToken == null) if (valueToken == null)
{ {
return defaultValue; return defaultValue;
} }
return valueToken.Value<bool>();
return valueToken.Value;
} }
private static int ReadInt(JToken cursor, string property, int defaultValue) private static int ReadInt(JsonObject cursor, string property, int defaultValue)
{ {
var valueToken = cursor[property]; var number = cursor.Value(property) as JsonNumber;
if (valueToken == null) if (number == null)
{ {
return defaultValue; return defaultValue;
} }
return valueToken.Value<int>();
}
private static string ReadString(JToken json) try
{
return json.Value<string>();
}
private static NuGetVersion ReadSemanticVersion(JToken json, string property)
{
var valueToken = json[property];
if (valueToken == null)
{ {
throw new ArgumentException($"lock file missing required property '{property}'", nameof(property)); var resultInInt = Convert.ToInt32(number.Raw);
return resultInInt;
}
catch (Exception ex)
{
// FormatException or OverflowException
throw FileFormatException.Create(ex, cursor);
} }
return NuGetVersion.Parse(valueToken.Value<string>());
} }
private static void WriteBool(JToken token, string property, bool value) private static string ReadString(JsonValue json)
{ {
token[property] = new JValue(value); if (json is JsonString)
} {
return (json as JsonString).Value;
private static JToken WriteString(string item) }
{ else if (json is JsonNull)
return item != null ? new JValue(item) : JValue.CreateNull(); {
} return null;
}
private static NuGetFramework ReadFrameworkName(JToken json) else
{ {
return json == null ? null : NuGetFramework.Parse(json.Value<string>()); throw FileFormatException.Create("The value type is not string.", json);
} }
private static JToken WriteFrameworkName(NuGetFramework item)
{
return item != null ? new JValue(item.DotNetFrameworkName) : JValue.CreateNull();
} }
} }
} }

View file

@ -1,6 +1,5 @@
using System.Linq; using System.Linq;
using Newtonsoft.Json; using Microsoft.Extensions.JsonParser.Sources;
using Newtonsoft.Json.Linq;
namespace Microsoft.Extensions.ProjectModel namespace Microsoft.Extensions.ProjectModel
{ {
@ -11,8 +10,8 @@ namespace Microsoft.Extensions.ProjectModel
public int Line { get; } public int Line { get; }
public int Column { get; } public int Column { get; }
internal PackIncludeEntry(string target, JToken json) internal PackIncludeEntry(string target, JsonValue json)
: this(target, ExtractValues(json), ((IJsonLineInfo)json).LineNumber, ((IJsonLineInfo)json).LinePosition) : this(target, ExtractValues(json), json.Line, json.Column)
{ {
} }
@ -24,18 +23,20 @@ namespace Microsoft.Extensions.ProjectModel
Column = column; Column = column;
} }
private static string[] ExtractValues(JToken json) private static string[] ExtractValues(JsonValue json)
{ {
if (json.Type == JTokenType.String) var valueAsString = json as JsonString;
if (valueAsString != null)
{ {
return new string[] { json.Value<string>() }; return new string[] { valueAsString.Value };
} }
if(json.Type == JTokenType.Array) var valueAsArray = json as JsonArray;
if(valueAsArray != null)
{ {
return json.Value<JArray>().Select(v => v.ToString()).ToArray(); return valueAsArray.Values.Select(v => v.ToString()).ToArray();
} }
return new string[0]; return new string[0];
} }
} }
} }

View file

@ -6,7 +6,7 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Microsoft.Extensions.FileSystemGlobbing; using Microsoft.Extensions.FileSystemGlobbing;
using Newtonsoft.Json.Linq; using Microsoft.Extensions.JsonParser.Sources;
namespace Microsoft.Extensions.ProjectModel namespace Microsoft.Extensions.ProjectModel
{ {
@ -33,7 +33,7 @@ namespace Microsoft.Extensions.ProjectModel
_matcher.AddExcludePatterns(ExcludePatterns); _matcher.AddExcludePatterns(ExcludePatterns);
} }
internal static PatternGroup Build(JObject rawProject, internal static PatternGroup Build(JsonObject rawProject,
string projectDirectory, string projectDirectory,
string projectFilePath, string projectFilePath,
string name, string name,
@ -120,4 +120,4 @@ namespace Microsoft.Extensions.ProjectModel
return string.Format("Pattern group: Literals [{0}] Includes [{1}] Excludes [{2}]", string.Join(", ", IncludeLiterals), string.Join(", ", IncludePatterns), string.Join(", ", ExcludePatterns)); return string.Format("Pattern group: Literals [{0}] Includes [{1}] Excludes [{2}]", string.Join(", ", IncludeLiterals), string.Join(", ", IncludePatterns), string.Join(", ", ExcludePatterns));
} }
} }
} }

View file

@ -5,7 +5,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Newtonsoft.Json.Linq; using Microsoft.Extensions.JsonParser.Sources;
namespace Microsoft.Extensions.ProjectModel namespace Microsoft.Extensions.ProjectModel
{ {
@ -13,7 +13,7 @@ namespace Microsoft.Extensions.ProjectModel
{ {
private static readonly char[] PatternSeparator = new[] { ';' }; private static readonly char[] PatternSeparator = new[] { ';' };
public static IEnumerable<string> GetPatternsCollection(JObject rawProject, public static IEnumerable<string> GetPatternsCollection(JsonObject rawProject,
string projectDirectory, string projectDirectory,
string projectFilePath, string projectFilePath,
string propertyName, string propertyName,
@ -22,21 +22,20 @@ namespace Microsoft.Extensions.ProjectModel
{ {
defaultPatterns = defaultPatterns ?? Enumerable.Empty<string>(); defaultPatterns = defaultPatterns ?? Enumerable.Empty<string>();
var prop = rawProject.Property(propertyName);
if (prop == null)
{
return CreateCollection(projectDirectory, propertyName, defaultPatterns, literalPath);
}
try try
{ {
var valueInString = prop.Value.Value<string>(); if (!rawProject.Keys.Contains(propertyName))
{
return CreateCollection(projectDirectory, propertyName, defaultPatterns, literalPath);
}
var valueInString = rawProject.ValueAsString(propertyName);
if (valueInString != null) if (valueInString != null)
{ {
return CreateCollection(projectDirectory, propertyName, new string[] { valueInString }, literalPath); return CreateCollection(projectDirectory, propertyName, new string[] { valueInString }, literalPath);
} }
var valuesInArray = prop.Value.Value<string[]>(); var valuesInArray = rawProject.ValueAsStringArray(propertyName);
if (valuesInArray != null) if (valuesInArray != null)
{ {
return CreateCollection(projectDirectory, propertyName, valuesInArray.Select(s => s.ToString()), literalPath); return CreateCollection(projectDirectory, propertyName, valuesInArray.Select(s => s.ToString()), literalPath);
@ -44,10 +43,10 @@ namespace Microsoft.Extensions.ProjectModel
} }
catch (Exception ex) catch (Exception ex)
{ {
throw FileFormatException.Create(ex, prop.Value, projectFilePath); throw FileFormatException.Create(ex, rawProject.Value(propertyName), projectFilePath);
} }
throw FileFormatException.Create("Value must be either string or array.", prop.Value, projectFilePath); throw FileFormatException.Create("Value must be either string or array.", rawProject.Value(propertyName), projectFilePath);
} }
private static IEnumerable<string> CreateCollection(string projectDirectory, string propertyName, IEnumerable<string> patternsStrings, bool literalPath) private static IEnumerable<string> CreateCollection(string projectDirectory, string propertyName, IEnumerable<string> patternsStrings, bool literalPath)

View file

@ -1,10 +1,12 @@
// Copyright (c) .NET Foundation. All rights reserved. // Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading;
using Microsoft.Extensions.JsonParser.Sources;
using Microsoft.Extensions.ProjectModel.Utilities; using Microsoft.Extensions.ProjectModel.Utilities;
using Newtonsoft.Json.Linq;
namespace Microsoft.Extensions.ProjectModel namespace Microsoft.Extensions.ProjectModel
{ {
@ -33,10 +35,10 @@ namespace Microsoft.Extensions.ProjectModel
private readonly string _projectDirectory; private readonly string _projectDirectory;
private readonly string _projectFilePath; private readonly string _projectFilePath;
private JObject _rawProject; private JsonObject _rawProject;
private bool _initialized; private bool _initialized;
internal ProjectFilesCollection(JObject rawProject, string projectDirectory, string projectFilePath) internal ProjectFilesCollection(JsonObject rawProject, string projectDirectory, string projectFilePath)
{ {
_projectDirectory = projectDirectory; _projectDirectory = projectDirectory;
_projectFilePath = projectFilePath; _projectFilePath = projectFilePath;
@ -81,12 +83,12 @@ namespace Microsoft.Extensions.ProjectModel
_namedResources = NamedResourceReader.ReadNamedResources(_rawProject, _projectFilePath); _namedResources = NamedResourceReader.ReadNamedResources(_rawProject, _projectFilePath);
// Files to be packed along with the project // Files to be packed along with the project
var packIncludeJson = _rawProject[PackIncludePropertyName] as JObject; var packIncludeJson = _rawProject.ValueAsJsonObject(PackIncludePropertyName);
if (packIncludeJson != null) if (packIncludeJson != null)
{ {
_packInclude = packIncludeJson _packInclude = packIncludeJson
.Properties() .Keys
.Select(prop => new PackIncludeEntry(prop.Name, prop.Value)) .Select(k => new PackIncludeEntry(k, packIncludeJson.Value(k)))
.ToList(); .ToList();
} }
else else

View file

@ -5,15 +5,14 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Microsoft.Extensions.JsonParser.Sources;
using Microsoft.Extensions.ProjectModel.Graph; using Microsoft.Extensions.ProjectModel.Graph;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NuGet.Frameworks; using NuGet.Frameworks;
using NuGet.Versioning; using NuGet.Versioning;
namespace Microsoft.Extensions.ProjectModel namespace Microsoft.Extensions.ProjectModel
{ {
internal class ProjectReader public class ProjectReader
{ {
public static Project GetProject(string projectFile) public static Project GetProject(string projectFile)
{ {
@ -33,11 +32,8 @@ namespace Microsoft.Extensions.ProjectModel
{ {
var project = new Project(); var project = new Project();
JObject rawProject; var reader = new StreamReader(stream);
using (var reader = new StreamReader(stream)) var rawProject = JsonDeserializer.Deserialize(reader) as JsonObject;
{
rawProject = JObject.Parse(reader.ReadToEnd());
}
if (rawProject == null) if (rawProject == null)
{ {
throw FileFormatException.Create( throw FileFormatException.Create(
@ -49,7 +45,7 @@ namespace Microsoft.Extensions.ProjectModel
project.Name = projectName; project.Name = projectName;
project.ProjectFilePath = Path.GetFullPath(projectPath); project.ProjectFilePath = Path.GetFullPath(projectPath);
var version = rawProject["version"]; var version = rawProject.Value("version") as JsonString;
if (version == null) if (version == null)
{ {
project.Version = new NuGetVersion("1.0.0"); project.Version = new NuGetVersion("1.0.0");
@ -59,7 +55,7 @@ namespace Microsoft.Extensions.ProjectModel
try try
{ {
var buildVersion = Environment.GetEnvironmentVariable("DNX_BUILD_VERSION"); var buildVersion = Environment.GetEnvironmentVariable("DNX_BUILD_VERSION");
project.Version = SpecifySnapshot(version.Value<string>(), buildVersion); project.Version = SpecifySnapshot(version, buildVersion);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -88,66 +84,68 @@ namespace Microsoft.Extensions.ProjectModel
} }
} }
project.Description = rawProject.Value<string>("description"); project.Description = rawProject.ValueAsString("description");
project.Summary = rawProject.Value<string>("summary"); project.Summary = rawProject.ValueAsString("summary");
project.Copyright = rawProject.Value<string>("copyright"); project.Copyright = rawProject.ValueAsString("copyright");
project.Title = rawProject.Value<string>("title"); project.Title = rawProject.ValueAsString("title");
project.WebRoot = rawProject.Value<string>("webroot"); project.WebRoot = rawProject.ValueAsString("webroot");
project.EntryPoint = rawProject.Value<string>("entryPoint"); project.EntryPoint = rawProject.ValueAsString("entryPoint");
project.ProjectUrl = rawProject.Value<string>("projectUrl"); project.ProjectUrl = rawProject.ValueAsString("projectUrl");
project.LicenseUrl = rawProject.Value<string>("licenseUrl"); project.LicenseUrl = rawProject.ValueAsString("licenseUrl");
project.IconUrl = rawProject.Value<string>("iconUrl"); project.IconUrl = rawProject.ValueAsString("iconUrl");
project.Authors = rawProject.ValueAsStringArray("authors"); project.Authors = rawProject.ValueAsStringArray("authors") ?? new string[] { };
project.Owners = rawProject.ValueAsStringArray("owners"); project.Owners = rawProject.ValueAsStringArray("owners") ?? new string[] { };
project.Tags = rawProject.ValueAsStringArray("tags"); project.Tags = rawProject.ValueAsStringArray("tags") ?? new string[] { };
project.Language = rawProject.Value<string>("language"); project.Language = rawProject.ValueAsString("language");
project.ReleaseNotes = rawProject.Value<string>("releaseNotes"); project.ReleaseNotes = rawProject.ValueAsString("releaseNotes");
project.RequireLicenseAcceptance = rawProject.Value<bool?>("requireLicenseAcceptance") ?? false; project.RequireLicenseAcceptance = rawProject.ValueAsBoolean("requireLicenseAcceptance", defaultValue: false);
project.IsLoadable = rawProject.Value<bool?>("loadable") ?? true; project.IsLoadable = rawProject.ValueAsBoolean("loadable", defaultValue: true);
// TODO: Move this to the dependencies node
project.EmbedInteropTypes = rawProject.ValueAsBoolean("embedInteropTypes", defaultValue: false);
project.Dependencies = new List<LibraryRange>(); project.Dependencies = new List<LibraryRange>();
// Project files // Project files
project.Files = new ProjectFilesCollection(rawProject, project.ProjectDirectory, project.ProjectFilePath); project.Files = new ProjectFilesCollection(rawProject, project.ProjectDirectory, project.ProjectFilePath);
var commands = rawProject.Value<JObject>("commands"); var commands = rawProject.Value("commands") as JsonObject;
if (commands != null) if (commands != null)
{ {
foreach (var prop in commands.Properties()) foreach (var key in commands.Keys)
{ {
var value = prop.Value.Value<string>(); var value = commands.ValueAsString(key);
if (value != null) if (value != null)
{ {
project.Commands[prop.Name] = value; project.Commands[key] = value;
} }
} }
} }
var scripts = rawProject.Value<JObject>("scripts"); var scripts = rawProject.Value("scripts") as JsonObject;
if (scripts != null) if (scripts != null)
{ {
foreach (var prop in scripts.Properties()) foreach (var key in scripts.Keys)
{ {
var stringValue = prop.Value<string>(); var stringValue = scripts.ValueAsString(key);
if (stringValue != null) if (stringValue != null)
{ {
project.Scripts[prop.Name] = new string[] { stringValue }; project.Scripts[key] = new string[] { stringValue };
continue; continue;
} }
var arrayValue = scripts.ValueAsStringArray(prop.Name); var arrayValue = scripts.ValueAsStringArray(key);
if (arrayValue != null) if (arrayValue != null)
{ {
project.Scripts[prop.Name] = arrayValue; project.Scripts[key] = arrayValue;
continue; continue;
} }
throw FileFormatException.Create( throw FileFormatException.Create(
string.Format("The value of a script in {0} can only be a string or an array of strings", Project.FileName), string.Format("The value of a script in {0} can only be a string or an array of strings", Project.FileName),
prop.Value, scripts.Value(key),
project.ProjectFilePath); project.ProjectFilePath);
} }
} }
@ -178,62 +176,61 @@ namespace Microsoft.Extensions.ProjectModel
} }
} }
return NuGetVersion.Parse(version); return new NuGetVersion(version);
} }
private static void PopulateDependencies( private static void PopulateDependencies(
string projectPath, string projectPath,
IList<LibraryRange> results, IList<LibraryRange> results,
JObject settings, JsonObject settings,
string propertyName, string propertyName,
bool isGacOrFrameworkReference) bool isGacOrFrameworkReference)
{ {
var dependencies = settings.Value<JObject>(propertyName); var dependencies = settings.ValueAsJsonObject(propertyName);
if (dependencies != null) if (dependencies != null)
{ {
foreach (var dependencyKey in dependencies.Properties()) foreach (var dependencyKey in dependencies.Keys)
{ {
if (string.IsNullOrEmpty(dependencyKey.Name)) if (string.IsNullOrEmpty(dependencyKey))
{ {
throw FileFormatException.Create( throw FileFormatException.Create(
"Unable to resolve dependency ''.", "Unable to resolve dependency ''.",
dependencyKey.Value, dependencies.Value(dependencyKey),
projectPath); projectPath);
} }
var dependencyValue = dependencyKey.Value; var dependencyValue = dependencies.Value(dependencyKey);
string dependencyVersionAsString = null; var dependencyTypeValue = LibraryDependencyType.Default;
LibraryDependencyType dependencyTypeValue = LibraryDependencyType.Default; JsonString dependencyVersionAsString = null;
LibraryType target = isGacOrFrameworkReference ? LibraryType.ReferenceAssembly : LibraryType.Unspecified; LibraryType target = isGacOrFrameworkReference ? LibraryType.ReferenceAssembly : LibraryType.Unspecified;
if (dependencyValue.Type == JTokenType.Object) if (dependencyValue is JsonObject)
{ {
// "dependencies" : { "Name" : { "version": "1.0", "type": "build", "target": "project" } } // "dependencies" : { "Name" : { "version": "1.0", "type": "build", "target": "project" } }
var dependencyValueAsObject = (JObject)dependencyValue; var dependencyValueAsObject = (JsonObject)dependencyValue;
dependencyVersionAsString = dependencyValueAsObject.Value<string>("version"); dependencyVersionAsString = dependencyValueAsObject.ValueAsString("version");
// Remove support for flags (we only support build and nothing right now) var type = dependencyValueAsObject.ValueAsString("type");
var type = dependencyValueAsObject.Value<string>("type");
if (type != null) if (type != null)
{ {
dependencyTypeValue = LibraryDependencyType.Parse(type); dependencyTypeValue = LibraryDependencyType.Parse(type.Value);
} }
// Read the target if specified // Read the target if specified
if (!isGacOrFrameworkReference) if (!isGacOrFrameworkReference)
{ {
LibraryType parsedTarget; LibraryType parsedTarget;
var targetStr = dependencyValueAsObject.Value<string>("target"); var targetStr = dependencyValueAsObject.ValueAsString("target");
if (!string.IsNullOrEmpty(targetStr) && LibraryType.TryParse(targetStr, out parsedTarget)) if (!string.IsNullOrEmpty(targetStr) && LibraryType.TryParse(targetStr, out parsedTarget))
{ {
target = parsedTarget; target = parsedTarget;
} }
} }
} }
else if (dependencyValue.Type == JTokenType.String) else if (dependencyValue is JsonString)
{ {
// "dependencies" : { "Name" : "1.0" } // "dependencies" : { "Name" : "1.0" }
dependencyVersionAsString = dependencyValue.Value<string>(); dependencyVersionAsString = (JsonString)dependencyValue;
} }
else else
{ {
@ -244,11 +241,11 @@ namespace Microsoft.Extensions.ProjectModel
} }
VersionRange dependencyVersionRange = null; VersionRange dependencyVersionRange = null;
if (!string.IsNullOrEmpty(dependencyVersionAsString)) if (!string.IsNullOrEmpty(dependencyVersionAsString?.Value))
{ {
try try
{ {
dependencyVersionRange = VersionRange.Parse(dependencyVersionAsString); dependencyVersionRange = VersionRange.Parse(dependencyVersionAsString.Value);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -260,47 +257,51 @@ namespace Microsoft.Extensions.ProjectModel
} }
results.Add(new LibraryRange( results.Add(new LibraryRange(
dependencyKey.Name, dependencyKey,
dependencyVersionRange, dependencyVersionRange,
target, target,
dependencyTypeValue, dependencyTypeValue,
projectPath, projectPath,
((IJsonLineInfo)dependencyKey.Value).LineNumber, dependencies.Value(dependencyKey).Line,
((IJsonLineInfo)dependencyKey.Value).LinePosition)); dependencies.Value(dependencyKey).Column));
} }
} }
} }
private static bool TryGetStringEnumerable(JObject parent, string property, out IEnumerable<string> result) private static bool TryGetStringEnumerable(JsonObject parent, string property, out IEnumerable<string> result)
{ {
var collection = new List<string>(); var collection = new List<string>();
var value = parent[property]; var valueInString = parent.ValueAsString(property);
if (value.Type == JTokenType.String) if (valueInString != null)
{ {
collection.Add(value.Value<string>()); collection.Add(valueInString);
}
else if (value.Type == JTokenType.Array)
{
collection.AddRange(value.Value<string[]>());
} }
else else
{ {
result = null; var valueInArray = parent.ValueAsStringArray(property);
return false; if (valueInArray != null)
{
collection.AddRange(valueInArray);
}
else
{
result = null;
return false;
}
} }
result = collection.SelectMany(v => v.Split(new[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries)); result = collection.SelectMany(value => value.Split(new[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries));
return true; return true;
} }
private void BuildTargetFrameworksAndConfigurations(Project project, JObject projectJsonObject, ICollection<DiagnosticMessage> diagnostics) private void BuildTargetFrameworksAndConfigurations(Project project, JsonObject projectJsonObject, ICollection<DiagnosticMessage> diagnostics)
{ {
// Get the shared compilationOptions // Get the shared compilationOptions
project._defaultCompilerOptions = GetCompilationOptions(projectJsonObject) ?? new CompilerOptions(); project._defaultCompilerOptions = GetCompilationOptions(projectJsonObject) ?? new CompilerOptions();
project._defaultTargetFrameworkConfiguration = new TargetFrameworkInformation project._defaultTargetFrameworkConfiguration = new TargetFrameworkInformation
{ {
Dependencies = new List<LibraryRange>().AsReadOnly() Dependencies = new List<LibraryRange>()
}; };
// Add default configurations // Add default configurations
@ -328,15 +329,15 @@ namespace Microsoft.Extensions.ProjectModel
} }
*/ */
var configurationsSection = projectJsonObject.Value<JObject>("configurations"); var configurationsSection = projectJsonObject.ValueAsJsonObject("configurations");
if (configurationsSection != null) if (configurationsSection != null)
{ {
foreach (var configKey in configurationsSection.Properties()) foreach (var configKey in configurationsSection.Keys)
{ {
var compilerOptions = GetCompilationOptions(configKey.Value<JObject>()); var compilerOptions = GetCompilationOptions(configurationsSection.ValueAsJsonObject(configKey));
// Only use this as a configuration if it's not a target framework // Only use this as a configuration if it's not a target framework
project._compilerOptionsByConfiguration[configKey.Name] = compilerOptions; project._compilerOptionsByConfiguration[configKey] = compilerOptions;
} }
} }
@ -352,15 +353,15 @@ namespace Microsoft.Extensions.ProjectModel
} }
*/ */
var frameworks = projectJsonObject.Value<JObject>("frameworks"); var frameworks = projectJsonObject.ValueAsJsonObject("frameworks");
if (frameworks != null) if (frameworks != null)
{ {
foreach (var frameworkKey in frameworks.Properties()) foreach (var frameworkKey in frameworks.Keys)
{ {
try try
{ {
var frameworkToken = frameworks.Value<JObject>(frameworkKey.Name); var frameworkToken = frameworks.ValueAsJsonObject(frameworkKey);
var success = BuildTargetFrameworkNode(project, frameworkKey.Name, frameworkToken); var success = BuildTargetFrameworkNode(project, frameworkKey, frameworkToken);
if (!success) if (!success)
{ {
diagnostics?.Add( diagnostics?.Add(
@ -369,12 +370,13 @@ namespace Microsoft.Extensions.ProjectModel
$"\"{frameworkKey}\" is an unsupported framework.", $"\"{frameworkKey}\" is an unsupported framework.",
project.ProjectFilePath, project.ProjectFilePath,
DiagnosticMessageSeverity.Error, DiagnosticMessageSeverity.Error,
frameworkToken)); frameworkToken.Line,
frameworkToken.Column));
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
throw FileFormatException.Create(ex, frameworkKey.Value, project.ProjectFilePath); throw FileFormatException.Create(ex, frameworks.Value(frameworkKey), project.ProjectFilePath);
} }
} }
} }
@ -386,7 +388,7 @@ namespace Microsoft.Extensions.ProjectModel
/// <param name="frameworkKey">The name of the framework</param> /// <param name="frameworkKey">The name of the framework</param>
/// <param name="frameworkValue">The Json object represent the settings</param> /// <param name="frameworkValue">The Json object represent the settings</param>
/// <returns>Returns true if it successes.</returns> /// <returns>Returns true if it successes.</returns>
private bool BuildTargetFrameworkNode(Project project, string frameworkKey, JObject frameworkValue) private bool BuildTargetFrameworkNode(Project project, string frameworkKey, JsonObject frameworkValue)
{ {
// If no compilation options are provided then figure them out from the node // If no compilation options are provided then figure them out from the node
var compilerOptions = GetCompilationOptions(frameworkValue) ?? var compilerOptions = GetCompilationOptions(frameworkValue) ??
@ -438,13 +440,13 @@ namespace Microsoft.Extensions.ProjectModel
frameworkDependencies.AddRange(frameworkAssemblies); frameworkDependencies.AddRange(frameworkAssemblies);
targetFrameworkInformation.Dependencies = frameworkDependencies; targetFrameworkInformation.Dependencies = frameworkDependencies;
targetFrameworkInformation.WrappedProject = frameworkValue.Value<string>("wrappedProject"); targetFrameworkInformation.WrappedProject = frameworkValue.ValueAsString("wrappedProject");
var binNode = frameworkValue.Value<JObject>("bin"); var binNode = frameworkValue.ValueAsJsonObject("bin");
if (binNode != null) if (binNode != null)
{ {
targetFrameworkInformation.AssemblyPath = binNode.Value<string>("assembly"); targetFrameworkInformation.AssemblyPath = binNode.ValueAsString("assembly");
targetFrameworkInformation.PdbPath = binNode.Value<string>("pdb"); targetFrameworkInformation.PdbPath = binNode.ValueAsString("pdb");
} }
project._compilerOptionsByFramework[frameworkName] = compilerOptions; project._compilerOptionsByFramework[frameworkName] = compilerOptions;
@ -453,9 +455,9 @@ namespace Microsoft.Extensions.ProjectModel
return true; return true;
} }
private static CompilerOptions GetCompilationOptions(JObject rawObject) private static CompilerOptions GetCompilationOptions(JsonObject rawObject)
{ {
var rawOptions = rawObject.Value<JObject>("compilationOptions"); var rawOptions = rawObject.ValueAsJsonObject("compilationOptions");
if (rawOptions == null) if (rawOptions == null)
{ {
return null; return null;
@ -463,20 +465,20 @@ namespace Microsoft.Extensions.ProjectModel
return new CompilerOptions return new CompilerOptions
{ {
Defines = rawOptions.Value<string[]>("define"), Defines = rawOptions.ValueAsStringArray("define"),
LanguageVersion = rawOptions.Value<string>("languageVersion"), LanguageVersion = rawOptions.ValueAsString("languageVersion"),
AllowUnsafe = rawOptions.Value<bool?>("allowUnsafe"), AllowUnsafe = rawOptions.ValueAsNullableBoolean("allowUnsafe"),
Platform = rawOptions.Value<string>("platform"), Platform = rawOptions.ValueAsString("platform"),
WarningsAsErrors = rawOptions.Value<bool?>("warningsAsErrors"), WarningsAsErrors = rawOptions.ValueAsNullableBoolean("warningsAsErrors"),
Optimize = rawOptions.Value<bool?>("optimize"), Optimize = rawOptions.ValueAsNullableBoolean("optimize"),
KeyFile = rawOptions.Value<string>("keyFile"), KeyFile = rawOptions.ValueAsString("keyFile"),
DelaySign = rawOptions.Value<bool?>("delaySign"), DelaySign = rawOptions.ValueAsNullableBoolean("delaySign"),
StrongName = rawOptions.Value<bool?>("strongName"), StrongName = rawOptions.ValueAsNullableBoolean("strongName"),
EmitEntryPoint = rawOptions.Value<bool?>("emitEntryPoint") EmitEntryPoint = rawOptions.ValueAsNullableBoolean("emitEntryPoint")
}; };
} }
public static string MakeDefaultTargetFrameworkDefine(NuGetFramework targetFramework) private static string MakeDefaultTargetFrameworkDefine(NuGetFramework targetFramework)
{ {
var shortName = targetFramework.GetTwoDigitShortFolderName(); var shortName = targetFramework.GetTwoDigitShortFolderName();

View file

@ -1,27 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Newtonsoft.Json.Linq
{
internal static class JsonExtensions
{
public static string[] ValueAsStringArray(this JObject self, string property)
{
var prop = self.Property(property);
if (prop != null)
{
if (prop.Value.Type == JTokenType.String)
{
return new string[] { prop.Value.ToString() };
}
else if (prop.Value.Type == JTokenType.Array)
{
return ((JArray)prop.Value).Select(t => t.ToString()).ToArray();
}
}
return new string[0];
}
}
}

View file

@ -3,53 +3,52 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using Newtonsoft.Json.Linq; using Microsoft.Extensions.JsonParser.Sources;
namespace Microsoft.Extensions.ProjectModel.Utilities namespace Microsoft.Extensions.ProjectModel.Utilities
{ {
internal static class NamedResourceReader internal static class NamedResourceReader
{ {
public static IDictionary<string, string> ReadNamedResources(JObject rawProject, string projectFilePath) public static IDictionary<string, string> ReadNamedResources(JsonObject rawProject, string projectFilePath)
{ {
var prop = rawProject.Property("namedResource"); if (!rawProject.Keys.Contains("namedResource"))
if(prop == null)
{ {
return new Dictionary<string, string>(); return new Dictionary<string, string>();
} }
var namedResourceToken = prop.Value as JObject; var namedResourceToken = rawProject.ValueAsJsonObject("namedResource");
if (namedResourceToken == null) if (namedResourceToken == null)
{ {
throw FileFormatException.Create("Value must be object.", prop.Value, projectFilePath); throw FileFormatException.Create("Value must be object.", rawProject.Value("namedResource"), projectFilePath);
} }
var namedResources = new Dictionary<string, string>(); var namedResources = new Dictionary<string, string>();
foreach (var namedResource in namedResourceToken) foreach (var namedResourceKey in namedResourceToken.Keys)
{ {
if (namedResource.Value.Type != JTokenType.String) var resourcePath = namedResourceToken.ValueAsString(namedResourceKey);
if (resourcePath == null)
{ {
throw FileFormatException.Create("Value must be string.", namedResource.Value, projectFilePath); throw FileFormatException.Create("Value must be string.", namedResourceToken.Value(namedResourceKey), projectFilePath);
} }
var resourcePath = namedResource.Value.Value<string>();
if (resourcePath.Contains("*")) if (resourcePath.Value.Contains("*"))
{ {
throw FileFormatException.Create("Value cannot contain wildcards.", namedResource.Value, projectFilePath); throw FileFormatException.Create("Value cannot contain wildcards.", resourcePath, projectFilePath);
} }
var resourceFileFullPath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(projectFilePath), resourcePath)); var resourceFileFullPath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(projectFilePath), resourcePath));
if (namedResources.ContainsKey(namedResource.Key)) if (namedResources.ContainsKey(namedResourceKey))
{ {
throw FileFormatException.Create( throw FileFormatException.Create(
$"The named resource {namedResource.Key} already exists.", string.Format("The named resource {0} already exists.", namedResourceKey),
namedResource.Value, resourcePath,
projectFilePath); projectFilePath);
} }
namedResources.Add( namedResources.Add(
namedResource.Key, namedResourceKey,
resourceFileFullPath); resourceFileFullPath);
} }
@ -73,4 +72,4 @@ namespace Microsoft.Extensions.ProjectModel.Utilities
} }
} }
} }
} }

View file

@ -13,9 +13,8 @@
"NuGet.Packaging": "3.2.0", "NuGet.Packaging": "3.2.0",
"Newtonsoft.Json": "7.0.1",
"Microsoft.Extensions.FileSystemGlobbing": "1.0.0-*", "Microsoft.Extensions.FileSystemGlobbing": "1.0.0-*",
"Microsoft.Extensions.JsonParser.Sources": { "type": "build", "version": "1.0.0-*" },
"Microsoft.Extensions.HashCodeCombiner.Sources": { "type": "build", "version": "1.0.0-*" } "Microsoft.Extensions.HashCodeCombiner.Sources": { "type": "build", "version": "1.0.0-*" }
}, },