Skip to content
Snippets Groups Projects
Commit 72685af6 authored by Frederik Carlier's avatar Frederik Carlier
Browse files

First step in adding support for merging domains

- Implement Equals, GetHashCode for the domain objects
- Add ProtocolMerge class, which for now detects which commands do not match
parent 5042bcfa
No related branches found
No related tags found
No related merge requests found
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MasterDevs.ChromeDevTools.ProtocolGenerator
{
static class CollectionExtensions
{
public static bool CollectionEqual<T>(this ICollection<T> x, ICollection<T> y)
{
if (x == null || y == null)
{
return false;
}
if(x.Count != y.Count)
{
return false;
}
return x.All(e => y.Contains(e));
}
public static int GetCollectionHashCode<T>(this ICollection<T> x)
{
int hash = 17;
unchecked
{
foreach (var e in x)
{
hash = hash * 23 + e.GetHashCode();
}
}
return hash;
}
}
}
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Linq;
namespace MasterDevs.ChromeDevTools.ProtocolGenerator
{
......@@ -46,5 +49,98 @@ namespace MasterDevs.ChromeDevTools.ProtocolGenerator
get;
set;
}
public override bool Equals(object obj)
{
var other = obj as Command;
if (other == null)
{
return false;
}
bool equals = base.Equals(obj);
equals &= this.Returns.SequenceEqual(other.Returns);
equals &= Property.Equals(this.Error, other.Error);
equals &= this.Handlers.CollectionEqual(other.Handlers);
equals &= this.Parameters.SequenceEqual(other.Parameters);
return equals;
}
public override int GetHashCode()
{
unchecked
{
int hash = base.GetHashCode();
hash = hash * 23 + this.Redirect.GetHashCode();
if (this.Error != null)
{
hash = hash * 23 + this.Error.GetHashCode();
}
hash = hash * 23 + this.Handlers.GetCollectionHashCode();
hash = hash * 23 + this.Parameters.GetCollectionHashCode();
return hash;
}
}
public override string ToString()
{
StringBuilder name = new StringBuilder();
if (this.Returns.Count > 0)
{
name.Append("(");
bool isFirst = true;
foreach (var p in this.Returns)
{
if (isFirst)
{
isFirst = false;
}
else
{
name.Append(", ");
}
name.Append(p.TypeName);
name.Append(" ");
name.Append(p.Name);
}
name.Append(") ");
}
else
{
name.Append("void ");
}
name.Append(this.Name);
name.Append("(");
bool isFirstParam = true;
foreach (var p in this.Parameters)
{
if (isFirstParam)
{
isFirstParam = false;
}
else
{
name.Append(", ");
}
name.Append(p.TypeName);
name.Append(" ");
name.Append(p.Name);
}
name.Append(")");
return name.ToString();
}
}
}
......@@ -50,14 +50,17 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="CollectionExtensions.cs" />
<Compile Include="Command.cs" />
<Compile Include="Domain.cs" />
<Compile Include="Event.cs" />
<Compile Include="NameEqualityComparer.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Property.cs" />
<Compile Include="Protocol.cs" />
<Compile Include="ProtocolItem.cs" />
<Compile Include="ProtocolMerger.cs" />
<Compile Include="Type.cs" />
<Compile Include="Version.cs" />
</ItemGroup>
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MasterDevs.ChromeDevTools.ProtocolGenerator
{
class NameEqualityComparer : EqualityComparer<ProtocolItem>
{
public static NameEqualityComparer Instance
{ get; } = new NameEqualityComparer();
public override bool Equals(ProtocolItem x, ProtocolItem y)
{
if (x == null || y == null)
{
return false;
}
return string.Equals(x.Name, y.Name, StringComparison.OrdinalIgnoreCase);
}
public override int GetHashCode(ProtocolItem obj)
{
if (obj == null)
{
throw new ArgumentNullException(nameof(obj));
}
return StringComparer.OrdinalIgnoreCase.GetHashCode(obj.Name);
}
}
}
......@@ -2,6 +2,7 @@
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
......@@ -23,20 +24,61 @@ namespace MasterDevs.ChromeDevTools.ProtocolGenerator
private static Dictionary<string, List<string>> _DomainEvents = new Dictionary<string, List<string>>();
private static Dictionary<string, string> _SimpleTypes = new Dictionary<string, string>();
private static Protocol LoadProtocol(string path)
private static Protocol LoadProtocol(string path, string alias)
{
string json = File.ReadAllText(path);
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.MissingMemberHandling = MissingMemberHandling.Error;
settings.MetadataPropertyHandling = MetadataPropertyHandling.Ignore;
Protocol p = JsonConvert.DeserializeObject<Protocol>(json, settings);
p.SourceFile = path;
p.Alias = alias;
foreach(var domain in p.Domains)
{
foreach(var command in domain.Commands)
{
command.SupportedBy.Add(alias);
}
foreach(var @event in domain.Events)
{
@event.SupportedBy.Add(alias);
}
foreach(var type in domain.Types)
{
type.SupportedBy.Add(alias);
}
}
return p;
}
private static void Main(string[] args)
{
var filePath = "protocol.json";
var protocolObject = LoadProtocol(filePath);
Dictionary<string, string> protocolFiles = new Dictionary<string, string>();
protocolFiles.Add("Chrome-0.1", "Inspector-0.1.json");
protocolFiles.Add("Chrome-1.0", "Inspector-1.0.json");
protocolFiles.Add("Chrome-1.1", "Inspector-1.1.json");
protocolFiles.Add("Chrome-Tip", "protocol.json");
protocolFiles.Add("iOS-7.0", "Inspector-iOS-7.0.json");
protocolFiles.Add("iOS-8.0", "Inspector-iOS-8.0.json");
protocolFiles.Add("iOS-9.0", "Inspector-iOS-9.0.json");
protocolFiles.Add("iOS-9.3", "Inspector-iOS-9.3.json");
Collection<Protocol> protocols = new Collection<Protocol>();
foreach(var protocolFile in protocolFiles)
{
protocols.Add(LoadProtocol(protocolFile.Value, protocolFile.Key));
}
Protocol protocolObject = new Protocol();
foreach(var protocol in protocols)
{
ProtocolMerger.Merge(protocol, protocolObject);
}
var outputFolder = "OutputProtocol";
if (args.Length > 0)
......
......@@ -4,6 +4,12 @@ namespace MasterDevs.ChromeDevTools.ProtocolGenerator
{
class Protocol
{
public Protocol()
{
this.Compatible = new Collection<string>();
this.Domains = new Collection<Domain>();
}
public Collection<string> Compatible
{
get;
......@@ -21,5 +27,17 @@ namespace MasterDevs.ChromeDevTools.ProtocolGenerator
get;
set;
}
public string SourceFile
{
get;
set;
}
public string Alias
{
get;
set;
}
}
}
namespace MasterDevs.ChromeDevTools.ProtocolGenerator
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace MasterDevs.ChromeDevTools.ProtocolGenerator
{
abstract class ProtocolItem
{
public ProtocolItem()
{
this.SupportedBy = new Collection<string>();
}
public virtual string Description
{
get;
......@@ -20,9 +29,64 @@
set;
}
public Collection<string> SupportedBy
{
get;
}
public override string ToString()
{
return this.Name;
}
public static bool Equals(ProtocolItem a, ProtocolItem b)
{
if (a == null && b == null)
{
return true;
}
if (a == null || b == null)
{
return false;
}
if (a.GetType() != b.GetType())
{
return false;
}
return a.Equals(b);
}
public override bool Equals(object obj)
{
// In the Equals method, we only include properties which would impact how
// messages are serialized over the wire. E.g.: because the description does not
// impact this, but the name does, the description is ignored but the name is included.
var other = obj as ProtocolItem;
if (other == null)
{
return false;
}
return string.Equals(other.Name, this.Name, StringComparison.OrdinalIgnoreCase);
}
public override int GetHashCode()
{
unchecked
{
int hash = 17;
if (this.Name != null)
{
hash = hash * 23 + StringComparer.OrdinalIgnoreCase.GetHashCode(this.Name);
}
return hash;
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MasterDevs.ChromeDevTools.ProtocolGenerator
{
class ProtocolMerger
{
public static void Merge(Protocol source, Protocol target)
{
foreach (var domain in source.Domains)
{
if (!target.Domains.Contains(domain, NameEqualityComparer.Instance))
{
target.Domains.Add(domain);
}
else
{
Merge(domain, target.Domains.Single(t => NameEqualityComparer.Instance.Equals(domain, t)));
}
}
}
static void Merge(Domain source, Domain target)
{
foreach (var command in source.Commands)
{
if (!target.Commands.Contains(command, NameEqualityComparer.Instance))
{
target.Commands.Add(command);
}
else
{
var targetCommand = target.Commands.Single(t => NameEqualityComparer.Instance.Equals(command, t));
if(!targetCommand.Equals(command))
{
Console.WriteLine($"{source.Name}:{command},{targetCommand}");
}
else
{
foreach (var v in command.SupportedBy)
{
targetCommand.SupportedBy.Add(v);
}
}
}
}
foreach (var @event in source.Events)
{
if (!target.Events.Contains(@event, NameEqualityComparer.Instance))
{
target.Events.Add(@event);
}
else
{
}
}
foreach (var type in source.Types)
{
if (!target.Types.Contains(type, NameEqualityComparer.Instance))
{
target.Types.Add(type);
}
else
{
}
}
}
}
}
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace MasterDevs.ChromeDevTools.ProtocolGenerator
......@@ -7,8 +9,8 @@ namespace MasterDevs.ChromeDevTools.ProtocolGenerator
{
public Type()
{
this.Enum = new Collection<string>();
this.Properties = new Collection<Property>();
this.Enum = new HashSet<string>();
this.Properties = new HashSet<Property>();
}
[JsonProperty(PropertyName = "Id")]
......@@ -25,13 +27,13 @@ namespace MasterDevs.ChromeDevTools.ProtocolGenerator
set;
}
public Collection<string> Enum
public HashSet<string> Enum
{
get;
set;
}
public Collection<Property> Properties
public HashSet<Property> Properties
{
get;
set;
......@@ -61,5 +63,77 @@ namespace MasterDevs.ChromeDevTools.ProtocolGenerator
get;
set;
}
public string TypeName
{
get
{
if (this.TypeReference != null)
{
return this.TypeReference;
}
else if (this.Items != null)
{
return this.Items.Name + "[]";
}
else if(this.Kind != null && this.Kind != "object")
{
return this.Kind;
}
else
{
return this.Name;
}
}
}
public override bool Equals(object obj)
{
var other = obj as Type;
if (other == null)
{
return false;
}
return base.Equals(obj)
&& string.Equals(this.Kind, other.Kind, StringComparison.OrdinalIgnoreCase)
&& this.Enum.SetEquals(other.Enum)
&& this.Properties.SetEquals(other.Properties)
&& Type.Equals(this.Items, other.Items)
&& this.MinItems == other.MinItems
&& this.MaxItems == other.MaxItems
&& string.Equals(this.TypeReference, other.TypeReference, StringComparison.OrdinalIgnoreCase);
}
public override int GetHashCode()
{
unchecked
{
int hash = base.GetHashCode();
if (this.Kind != null)
{
hash = hash * 23 + StringComparer.OrdinalIgnoreCase.GetHashCode(this.Kind);
}
hash = hash * 23 + this.Enum.GetCollectionHashCode();
hash = hash * 23 + this.Properties.GetCollectionHashCode();
if (this.Items != null)
{
hash = hash * 23 + this.Items.GetHashCode();
}
hash = hash * 23 + this.MinItems.GetHashCode();
hash = hash * 23 + this.MaxItems.GetHashCode();
if (this.TypeReference != null)
{
hash = hash * 23 + StringComparer.OrdinalIgnoreCase.GetHashCode(this.TypeReference);
}
return hash;
}
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment