diff --git a/Bond.Parser.CLI/Bond.Parser.CLI.csproj b/Bond.Parser.CLI/Bond.Parser.CLI.csproj
index 369266a..19d62f7 100644
--- a/Bond.Parser.CLI/Bond.Parser.CLI.csproj
+++ b/Bond.Parser.CLI/Bond.Parser.CLI.csproj
@@ -17,7 +17,7 @@
true
bbc
bbc
- 0.2.0
+ 0.2.1
Mirco De Zorzi
Bond IDL compiler and toolchain
Bond.Parser.CLI
diff --git a/Bond.Parser.CLI/Program.cs b/Bond.Parser.CLI/Program.cs
index da9c7da..5f4d780 100644
--- a/Bond.Parser.CLI/Program.cs
+++ b/Bond.Parser.CLI/Program.cs
@@ -45,10 +45,12 @@ static void ShowHelp()
Console.WriteLine("Parse Options:");
Console.WriteLine(" -v, --verbose Show detailed AST output");
Console.WriteLine(" --json Output AST as JSON (Bond schema format)");
+ Console.WriteLine(" --ignore-imports Parse without resolving imports or types");
Console.WriteLine();
Console.WriteLine("Breaking Options:");
Console.WriteLine(" --against Reference schema to compare against (file path or .git#branch=name)");
Console.WriteLine(" --error-format Output format: text, json (default: text)");
+ Console.WriteLine(" --ignore-imports Compare without resolving imports or types");
Console.WriteLine();
Console.WriteLine("Examples:");
Console.WriteLine(" bbc parse schema.bond");
@@ -71,8 +73,10 @@ static async Task RunParseCommand(string[] args)
var filePath = args[0];
var verbose = args.Contains("--verbose") || args.Contains("-v");
var jsonOutput = args.Contains("--json");
+ var ignoreImports = args.Contains("--ignore-imports");
- var result = await ParserFacade.ParseFileAsync(filePath);
+ var parseOptions = new ParseOptions(IgnoreImports: ignoreImports);
+ var result = await ParserFacade.ParseFileAsync(filePath, options: parseOptions);
if (!result.Success)
{
@@ -116,6 +120,7 @@ static async Task RunBreakingCommand(string[] args)
var againstIndex = Array.FindIndex(args, a => a == "--against");
var formatIndex = Array.FindIndex(args, a => a.StartsWith("--error-format"));
var verbose = args.Contains("-v") || args.Contains("--verbose");
+ var ignoreImports = args.Contains("--ignore-imports");
if (againstIndex < 0 || againstIndex + 1 >= args.Length)
{
@@ -139,17 +144,22 @@ static async Task RunBreakingCommand(string[] args)
}
}
- var referenceFile = await ResolveReference(against, filePath);
- if (referenceFile == null)
+ var reference = await ResolveReference(against, filePath);
+ if (reference == null)
{
WriteError($"Error: Could not resolve reference: {against}");
return 1;
}
- return await CheckBreaking(referenceFile, filePath, errorFormat, verbose);
+ return await CheckBreaking(reference, filePath, errorFormat, verbose, ignoreImports);
}
- static async Task ResolveReference(string reference, string currentFilePath)
+ private sealed record ResolvedReference(
+ string FilePath,
+ string? Content,
+ ImportResolver? ImportResolver);
+
+ static async Task ResolveReference(string reference, string currentFilePath)
{
if (reference.StartsWith(".git#"))
{
@@ -158,13 +168,13 @@ static async Task RunBreakingCommand(string[] args)
if (File.Exists(reference))
{
- return reference;
+ return new ResolvedReference(Path.GetFullPath(reference), null, null);
}
return null;
}
- static async Task ResolveGitReference(string gitRef, string currentFilePath)
+ static async Task ResolveGitReference(string gitRef, string currentFilePath)
{
var parts = gitRef.Split('#');
if (parts.Length != 2)
@@ -190,18 +200,20 @@ static async Task RunBreakingCommand(string[] args)
var fullPath = Path.GetFullPath(currentFilePath);
var gitRelativePath = Path.GetRelativePath(gitRoot, fullPath).Replace('\\', '/');
+ if (gitRelativePath.StartsWith("..") || Path.IsPathRooted(gitRelativePath))
+ {
+ return null;
+ }
- var content = await RunGitCommand($"show {refName}:{gitRelativePath}");
+ var content = await RunGitCommand($"show {refName}:{gitRelativePath}", gitRoot);
if (content == null)
{
return null;
}
- var tempFile = Path.GetTempFileName();
- var tempBondFile = Path.ChangeExtension(tempFile, ".bond");
- await File.WriteAllTextAsync(tempBondFile, content);
-
- return tempBondFile;
+ var virtualPath = Path.GetFullPath(Path.Combine(gitRoot, gitRelativePath));
+ var importResolver = CreateGitAwareImportResolver(gitRoot, refName);
+ return new ResolvedReference(virtualPath, content, importResolver);
}
catch
{
@@ -209,7 +221,7 @@ static async Task RunBreakingCommand(string[] args)
}
}
- static async Task RunGitCommand(string arguments)
+ static async Task RunGitCommand(string arguments, string? workingDirectory = null)
{
var process = new System.Diagnostics.Process
{
@@ -220,6 +232,7 @@ static async Task RunBreakingCommand(string[] args)
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
+ WorkingDirectory = workingDirectory ?? Environment.CurrentDirectory,
CreateNoWindow = true
}
};
@@ -231,15 +244,32 @@ static async Task RunBreakingCommand(string[] args)
return process.ExitCode == 0 ? output.Trim() : null;
}
- static async Task CheckBreaking(string oldFilePath, string newFilePath, string errorFormat, bool verbose)
+ static async Task CheckBreaking(ResolvedReference oldSchema, string newFilePath, string errorFormat, bool verbose, bool ignoreImports)
{
- var oldResult = await ParserFacade.ParseFileAsync(oldFilePath);
+ var parseOptions = new ParseOptions(IgnoreImports: ignoreImports);
+ ParseResult oldResult;
+ if (oldSchema.Content != null)
+ {
+ oldResult = await ParserFacade.ParseContentAsync(
+ oldSchema.Content,
+ oldSchema.FilePath,
+ oldSchema.ImportResolver,
+ parseOptions);
+ }
+ else
+ {
+ oldResult = await ParserFacade.ParseFileAsync(
+ oldSchema.FilePath,
+ oldSchema.ImportResolver,
+ default,
+ parseOptions);
+ }
if (!oldResult.Success)
{
- return OutputParseError(errorFormat, oldResult.Errors, "Failed to parse reference schema", oldFilePath);
+ return OutputParseError(errorFormat, oldResult.Errors, "Failed to parse reference schema", oldSchema.FilePath);
}
- var newResult = await ParserFacade.ParseFileAsync(newFilePath);
+ var newResult = await ParserFacade.ParseFileAsync(newFilePath, options: parseOptions);
if (!newResult.Success)
{
return OutputParseError(errorFormat, newResult.Errors, "Failed to parse current schema", newFilePath);
@@ -274,6 +304,34 @@ static async Task CheckBreaking(string oldFilePath, string newFilePath, str
return 0;
}
+ static ImportResolver CreateGitAwareImportResolver(string gitRoot, string refName)
+ {
+ return async (currentFile, importPath) =>
+ {
+ var currentDir = Path.GetDirectoryName(currentFile) ?? gitRoot;
+ var absolutePath = Path.GetFullPath(Path.Combine(currentDir, importPath));
+
+ var relativePath = Path.GetRelativePath(gitRoot, absolutePath).Replace('\\', '/');
+ var inRepo = !relativePath.StartsWith("..") && !Path.IsPathRooted(relativePath);
+ if (inRepo)
+ {
+ var contentFromGit = await RunGitCommand($"show {refName}:{relativePath}", gitRoot);
+ if (contentFromGit != null)
+ {
+ return (absolutePath, contentFromGit);
+ }
+ }
+
+ if (File.Exists(absolutePath))
+ {
+ var content = await File.ReadAllTextAsync(absolutePath);
+ return (absolutePath, content);
+ }
+
+ throw new FileNotFoundException($"Imported file not found: {importPath}", absolutePath);
+ };
+ }
+
static int OutputParseError(string errorFormat, List errors, string message, string filePath)
{
if (errorFormat == "json")
diff --git a/Bond.Parser.Tests/CompatibilityTests.cs b/Bond.Parser.Tests/CompatibilityTests.cs
index 0edcc5b..c078c01 100644
--- a/Bond.Parser.Tests/CompatibilityTests.cs
+++ b/Bond.Parser.Tests/CompatibilityTests.cs
@@ -1,3 +1,6 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Bond.Parser.Compatibility;
@@ -527,4 +530,64 @@ struct User {
}
#endregion
+
+ #region Issues
+
+ [Fact]
+ public async Task BreakingCheck_WithImports_ResolvesTypes()
+ {
+ var root = Path.Combine(Path.GetTempPath(), "bond-parser-tests", Guid.NewGuid().ToString("N"));
+ var mainPath = Path.Combine(root, "schema.bond");
+ var commonPath = Path.Combine(root, "common.bond");
+
+ var commonSchema = """
+ namespace Test
+ struct Common { 0: required int32 id; }
+ """;
+
+ var oldSchema = """
+ import "common.bond"
+ namespace Test
+ struct User { 0: required Common c; }
+ """;
+
+ var newSchema = """
+ import "common.bond"
+ namespace Test
+ struct User {
+ 0: required Common c;
+ 1: optional int32 age;
+ }
+ """;
+
+ var files = new Dictionary(StringComparer.Ordinal)
+ {
+ [commonPath] = commonSchema
+ };
+
+ ImportResolver resolver = (currentFile, importPath) =>
+ {
+ var currentDir = Path.GetDirectoryName(currentFile) ?? root;
+ var absolutePath = Path.GetFullPath(Path.Combine(currentDir, importPath));
+ if (!files.TryGetValue(absolutePath, out var content))
+ {
+ throw new FileNotFoundException($"Imported file not found: {importPath}", absolutePath);
+ }
+ return Task.FromResult((absolutePath, content));
+ };
+
+ var oldResult = await ParserFacade.ParseContentAsync(oldSchema, mainPath, resolver);
+ oldResult.Success.Should().BeTrue($"parsing should succeed but got errors: {string.Join(", ", oldResult.Errors.Select(e => e.Message))}");
+
+ var newResult = await ParserFacade.ParseContentAsync(newSchema, mainPath, resolver);
+ newResult.Success.Should().BeTrue($"parsing should succeed but got errors: {string.Join(", ", newResult.Errors.Select(e => e.Message))}");
+
+ var changes = _checker.CheckCompatibility(oldResult.Ast!, newResult.Ast!);
+
+ changes.Should().Contain(c =>
+ c.Category == ChangeCategory.Compatible &&
+ c.Description.Contains("age"));
+ }
+
+ #endregion
}
diff --git a/Bond.Parser/Json/BondJsonConverter.cs b/Bond.Parser/Json/BondJsonConverter.cs
index 7133de3..7fce8f5 100644
--- a/Bond.Parser/Json/BondJsonConverter.cs
+++ b/Bond.Parser/Json/BondJsonConverter.cs
@@ -9,7 +9,7 @@ namespace Bond.Parser.Json;
///
public class BondJsonConverter : JsonConverter
{
- public override Syntax.Bond? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ public override Syntax.Bond Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
throw new NotSupportedException("Deserialization not implemented");
}
diff --git a/Bond.Parser/Json/BondTypeJsonConverter.cs b/Bond.Parser/Json/BondTypeJsonConverter.cs
index 4f3a336..7918f3c 100644
--- a/Bond.Parser/Json/BondTypeJsonConverter.cs
+++ b/Bond.Parser/Json/BondTypeJsonConverter.cs
@@ -10,7 +10,7 @@ namespace Bond.Parser.Json;
///
public class BondTypeJsonConverter : JsonConverter
{
- public override BondType? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ public override BondType Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
throw new NotSupportedException("Deserialization not implemented");
}
diff --git a/Bond.Parser/Json/DeclarationJsonConverter.cs b/Bond.Parser/Json/DeclarationJsonConverter.cs
index 1f5a6db..54bf4ce 100644
--- a/Bond.Parser/Json/DeclarationJsonConverter.cs
+++ b/Bond.Parser/Json/DeclarationJsonConverter.cs
@@ -11,7 +11,7 @@ namespace Bond.Parser.Json;
///
public class DeclarationJsonConverter : JsonConverter
{
- public override Declaration? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ public override Declaration Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
throw new NotSupportedException("Deserialization not implemented");
}
diff --git a/Bond.Parser/Json/DefaultJsonConverter.cs b/Bond.Parser/Json/DefaultJsonConverter.cs
index 88d8edc..a9cd744 100644
--- a/Bond.Parser/Json/DefaultJsonConverter.cs
+++ b/Bond.Parser/Json/DefaultJsonConverter.cs
@@ -10,7 +10,7 @@ namespace Bond.Parser.Json;
///
public class DefaultJsonConverter : JsonConverter
{
- public override Default? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ public override Default Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
throw new NotSupportedException("Deserialization not implemented");
}
diff --git a/Bond.Parser/Json/FieldJsonConverter.cs b/Bond.Parser/Json/FieldJsonConverter.cs
index e36ea97..f727d57 100644
--- a/Bond.Parser/Json/FieldJsonConverter.cs
+++ b/Bond.Parser/Json/FieldJsonConverter.cs
@@ -10,7 +10,7 @@ namespace Bond.Parser.Json;
///
public class FieldJsonConverter : JsonConverter
{
- public override Field? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ public override Field Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
throw new NotSupportedException("Deserialization not implemented");
}
diff --git a/Bond.Parser/Json/MethodJsonConverter.cs b/Bond.Parser/Json/MethodJsonConverter.cs
index e5a2243..aa96923 100644
--- a/Bond.Parser/Json/MethodJsonConverter.cs
+++ b/Bond.Parser/Json/MethodJsonConverter.cs
@@ -10,7 +10,7 @@ namespace Bond.Parser.Json;
///
public class MethodTypeJsonConverter : JsonConverter
{
- public override MethodType? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ public override MethodType Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
throw new NotSupportedException("Deserialization not implemented");
}
@@ -42,7 +42,7 @@ public override void Write(Utf8JsonWriter writer, MethodType value, JsonSerializ
///
public class MethodJsonConverter : JsonConverter
{
- public override Method? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ public override Method Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
throw new NotSupportedException("Deserialization not implemented");
}
diff --git a/Bond.Parser/Json/SimpleTypeConverters.cs b/Bond.Parser/Json/SimpleTypeConverters.cs
index 324567c..fe002d8 100644
--- a/Bond.Parser/Json/SimpleTypeConverters.cs
+++ b/Bond.Parser/Json/SimpleTypeConverters.cs
@@ -10,7 +10,7 @@ namespace Bond.Parser.Json;
///
public class AttributeJsonConverter : JsonConverter
{
- public override Syntax.Attribute? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ public override Syntax.Attribute Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
throw new NotSupportedException("Deserialization not implemented");
}
@@ -34,7 +34,7 @@ public override void Write(Utf8JsonWriter writer, Syntax.Attribute value, JsonSe
///
public class NamespaceJsonConverter : JsonConverter
{
- public override Namespace? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ public override Namespace Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
throw new NotSupportedException("Deserialization not implemented");
}
@@ -61,7 +61,7 @@ public override void Write(Utf8JsonWriter writer, Namespace value, JsonSerialize
///
public class TypeParamJsonConverter : JsonConverter
{
- public override TypeParam? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ public override TypeParam Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
throw new NotSupportedException("Deserialization not implemented");
}
@@ -97,7 +97,7 @@ public override void Write(Utf8JsonWriter writer, TypeParam value, JsonSerialize
///
public class ConstantJsonConverter : JsonConverter
{
- public override Constant? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ public override Constant Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
throw new NotSupportedException("Deserialization not implemented");
}
@@ -128,7 +128,7 @@ public override void Write(Utf8JsonWriter writer, Constant value, JsonSerializer
///
public class ImportJsonConverter : JsonConverter
{
- public override Import? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ public override Import Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
throw new NotSupportedException("Deserialization not implemented");
}
diff --git a/Bond.Parser/Parser/AstBuilder.cs b/Bond.Parser/Parser/AstBuilder.cs
index bf02318..f9e8eb0 100644
--- a/Bond.Parser/Parser/AstBuilder.cs
+++ b/Bond.Parser/Parser/AstBuilder.cs
@@ -50,7 +50,7 @@ public override Namespace VisitNamespace(BondParser.NamespaceContext context)
return new Namespace(lang, name);
}
- public override object? VisitLanguage(BondParser.LanguageContext context)
+ public override object VisitLanguage(BondParser.LanguageContext context)
{
return context.GetText() switch
{
@@ -157,11 +157,11 @@ public override Declaration VisitStructDecl(BondParser.StructDeclContext context
Declaration result;
if (context.structView() != null)
{
- result = VisitStructView(context.structView(), name, typeParams, attributes)!;
+ result = VisitStructView(name, typeParams, attributes);
}
else if (context.structDef() != null)
{
- result = VisitStructDef(context.structDef(), name, typeParams, attributes)!;
+ result = VisitStructDef(context.structDef(), name, typeParams, attributes);
}
else
{
@@ -174,7 +174,7 @@ public override Declaration VisitStructDecl(BondParser.StructDeclContext context
return result;
}
- private StructDeclaration VisitStructView(BondParser.StructViewContext context, string name, TypeParam[] typeParams, Syntax.Attribute[] attributes)
+ private StructDeclaration VisitStructView(string name, TypeParam[] typeParams, Syntax.Attribute[] attributes)
{
return new StructDeclaration
{
@@ -419,7 +419,7 @@ public override Field VisitField(BondParser.FieldContext context)
return new Field(attributes, ordinal, modifier, type, name, defaultValue);
}
- public override object? VisitModifier(BondParser.ModifierContext context)
+ public override object VisitModifier(BondParser.ModifierContext context)
{
if (context.REQUIRED_OPTIONAL() != null)
{
diff --git a/Bond.Parser/Parser/ParserFacade.cs b/Bond.Parser/Parser/ParserFacade.cs
index b604086..aa260ce 100644
--- a/Bond.Parser/Parser/ParserFacade.cs
+++ b/Bond.Parser/Parser/ParserFacade.cs
@@ -33,15 +33,19 @@ List Errors
///
/// Main facade for parsing Bond files
///
+public sealed record ParseOptions(bool IgnoreImports = false);
+
public static class ParserFacade
{
+
///
/// Parses a Bond file from a file path
///
public static async Task ParseFileAsync(
string filePath,
ImportResolver? importResolver = null,
- CancellationToken cancellationToken = default)
+ CancellationToken cancellationToken = default,
+ ParseOptions? options = null)
{
if (!File.Exists(filePath))
{
@@ -51,24 +55,52 @@ public static async Task ParseFileAsync(
var content = await File.ReadAllTextAsync(filePath, cancellationToken);
var absolutePath = Path.GetFullPath(filePath);
- return await ParseContentAsync(content, absolutePath, importResolver ?? DefaultImportResolver.Resolve);
+ return await ParseContentInternalAsync(
+ content,
+ absolutePath,
+ importResolver ?? DefaultImportResolver.Resolve,
+ options);
}
///
/// Parses Bond content from a string without file path context
///
- public static Task ParseStringAsync(string content, ImportResolver? importResolver = null)
+ public static Task ParseStringAsync(
+ string content,
+ ImportResolver? importResolver = null,
+ ParseOptions? options = null)
+ {
+ return ParseContentInternalAsync(
+ content,
+ "",
+ importResolver ?? DefaultImportResolver.Resolve,
+ options);
+ }
+
+ ///
+ /// Parses Bond content from a string with file path context
+ ///
+ public static Task ParseContentAsync(
+ string content,
+ string filePath,
+ ImportResolver? importResolver = null,
+ ParseOptions? options = null)
{
- return ParseContentAsync(content, "", importResolver ?? DefaultImportResolver.Resolve);
+ return ParseContentInternalAsync(
+ content,
+ filePath,
+ importResolver ?? DefaultImportResolver.Resolve,
+ options);
}
///
/// Parses Bond content from a string
///
- private static async Task ParseContentAsync(
+ private static async Task ParseContentInternalAsync(
string content,
string filePath,
- ImportResolver importResolver)
+ ImportResolver importResolver,
+ ParseOptions? options)
{
var errors = new List();
@@ -93,6 +125,11 @@ private static async Task ParseContentAsync(
var astBuilder = new AstBuilder();
var ast = (Syntax.Bond)astBuilder.Visit(parseTree)!;
+ if (options?.IgnoreImports == true)
+ {
+ return new ParseResult(ast, errors);
+ }
+
// Perform semantic analysis
var symbolTable = new SymbolTable();
var analyzer = new SemanticAnalyzer(symbolTable, importResolver, filePath);
diff --git a/Bond.Parser/Parser/SemanticAnalyzer.cs b/Bond.Parser/Parser/SemanticAnalyzer.cs
index b50a467..f469993 100644
--- a/Bond.Parser/Parser/SemanticAnalyzer.cs
+++ b/Bond.Parser/Parser/SemanticAnalyzer.cs
@@ -39,7 +39,7 @@ public async Task AnalyzeAsync(Syntax.Bond bond)
foreach (var declaration in bond.Declarations)
{
_symbolTable.AddDeclaration(declaration, bond.Namespaces);
- ValidateDeclaration(declaration, bond.Namespaces);
+ ValidateDeclaration(declaration);
}
}
@@ -82,7 +82,7 @@ private static Syntax.Bond ParseContent(string content, string filePath)
return (Syntax.Bond)astBuilder.Visit(parseTree)!;
}
- private void ValidateDeclaration(Declaration declaration, Namespace[] namespaces)
+ private void ValidateDeclaration(Declaration declaration)
{
switch (declaration)
{
diff --git a/Bond.Parser/Parser/TypeResolver.cs b/Bond.Parser/Parser/TypeResolver.cs
index 8b420c0..bcf8de2 100644
--- a/Bond.Parser/Parser/TypeResolver.cs
+++ b/Bond.Parser/Parser/TypeResolver.cs
@@ -153,7 +153,6 @@ private MethodType ResolveMethodType(MethodType methodType, Namespace[] namespac
{
MethodType.Unary unary => new MethodType.Unary(ResolveType(unary.Type, namespaces)),
MethodType.Streaming streaming => new MethodType.Streaming(ResolveType(streaming.Type, namespaces)),
- MethodType.Void => methodType,
_ => methodType
};
}
diff --git a/Bond.Parser/Parser/TypeValidator.cs b/Bond.Parser/Parser/TypeValidator.cs
index 78e297f..5c24948 100644
--- a/Bond.Parser/Parser/TypeValidator.cs
+++ b/Bond.Parser/Parser/TypeValidator.cs
@@ -1,5 +1,4 @@
using System;
-using System.Numerics;
using Bond.Parser.Syntax;
using Bond.Parser.Util;
diff --git a/version b/version
index 0ea3a94..0c62199 100644
--- a/version
+++ b/version
@@ -1 +1 @@
-0.2.0
+0.2.1