Browse Source

Add work-in-progress TypeScript interface bindings generator.

java
Joao Matos 5 years ago committed by João Matos
parent
commit
c6e263e269
  1. 4
      src/CLI/CLI.cs
  2. 9
      src/Generator/Driver.cs
  3. 3
      src/Generator/Generator.cs
  4. 41
      src/Generator/Generators/TS/TSGenerator.cs
  5. 505
      src/Generator/Generators/TS/TSSources.cs
  6. 166
      src/Generator/Generators/TS/TSTypePrinter.cs
  7. 6
      src/Generator/Generators/TypePrinter.cs
  8. 1
      src/Generator/Passes/CheckDuplicatedNamesPass.cs
  9. 3
      tests2/ts/.gitignore
  10. 32
      tests2/ts/test.sh
  11. 73
      tests2/ts/test.ts
  12. 13
      tests2/ts/tsconfig.json

4
src/CLI/CLI.cs

@ -225,6 +225,10 @@ namespace CppSharp @@ -225,6 +225,10 @@ namespace CppSharp
case "qjs":
options.Kind = CppSharp.Generators.GeneratorKind.QuickJS;
return;
case "ts":
case "typescript":
options.Kind = CppSharp.Generators.GeneratorKind.TypeScript;
return;
}
errorMessages.Add($"Unknown generator kind: {generator}.");

9
src/Generator/Driver.cs

@ -8,6 +8,7 @@ using CppSharp.Generators.C; @@ -8,6 +8,7 @@ using CppSharp.Generators.C;
using CppSharp.Generators.CLI;
using CppSharp.Generators.Cpp;
using CppSharp.Generators.CSharp;
using CppSharp.Generators.TS;
using CppSharp.Parser;
using CppSharp.Passes;
using CppSharp.Utils;
@ -46,6 +47,8 @@ namespace CppSharp @@ -46,6 +47,8 @@ namespace CppSharp
return new QuickJSGenerator(Context);
case GeneratorKind.NAPI:
return new NAPIGenerator(Context);
case GeneratorKind.TypeScript:
return new TSGenerator(Context);
}
throw new NotImplementedException();
@ -238,7 +241,11 @@ namespace CppSharp @@ -238,7 +241,11 @@ namespace CppSharp
TranslationUnitPasses.AddPass(new CheckMacroPass());
TranslationUnitPasses.AddPass(new CheckStaticClass());
TranslationUnitPasses.AddPass(new CheckAmbiguousFunctions());
if (Options.IsCLIGenerator || Options.IsCSharpGenerator || Options.IsCppGenerator)
{
TranslationUnitPasses.AddPass(new CheckAmbiguousFunctions());
}
TranslationUnitPasses.AddPass(new ConstructorToConversionOperatorPass());
TranslationUnitPasses.AddPass(new MarshalPrimitivePointersAsRefTypePass());

3
src/Generator/Generator.cs

@ -18,7 +18,8 @@ namespace CppSharp.Generators @@ -18,7 +18,8 @@ namespace CppSharp.Generators
Java,
Swift,
QuickJS,
NAPI
NAPI,
TypeScript
}
/// <summary>

41
src/Generator/Generators/TS/TSGenerator.cs

@ -0,0 +1,41 @@ @@ -0,0 +1,41 @@
using System.Collections.Generic;
using CppSharp.AST;
using CppSharp.Generators.C;
using CppSharp.Passes;
namespace CppSharp.Generators.TS
{
/// <summary>
/// C++ generator responsible for driving the generation of source and
/// header files.
/// </summary>
public class TSGenerator : CGenerator
{
private readonly TSTypePrinter typePrinter;
public TSGenerator(BindingContext context) : base(context)
{
typePrinter = new TSTypePrinter(Context);
}
public override List<CodeGenerator> Generate(IEnumerable<TranslationUnit> units)
{
var outputs = new List<CodeGenerator>();
var header = new TSSources(Context, units);
outputs.Add(header);
return outputs;
}
public override bool SetupPasses()
{
return true;
}
protected override string TypePrinterDelegate(Type type)
{
return type.Visit(typePrinter).ToString();
}
}
}

505
src/Generator/Generators/TS/TSSources.cs

@ -0,0 +1,505 @@ @@ -0,0 +1,505 @@
using System;
using System.Collections.Generic;
using System.Linq;
using CppSharp.AST;
using CppSharp.AST.Extensions;
using CppSharp.Generators.C;
using CppSharp.Generators.CLI;
namespace CppSharp.Generators.TS
{
/// <summary>
/// Generates TypeScript interface files.
/// </summary>
public class TSSources : CCodeGenerator
{
public TSSources(BindingContext context, IEnumerable<TranslationUnit> units)
: base(context, units)
{
typePrinter = new TSTypePrinter(Context);
}
public override string FileExtension => "d.ts";
public override bool GenerateSemicolonAsDeclarationTerminator => false;
public virtual bool GenerateNamespaces => true;
public virtual bool GenerateSelectiveImports => false;
public override void Process()
{
GenerateFilePreamble(CommentKind.BCPL);
if (GenerateSelectiveImports)
GenerateImports();
else
GenerateWildcardImports();
GenerateMain();
}
public virtual void GenerateMain()
{
VisitTranslationUnit(TranslationUnit);
}
public virtual Dictionary<TranslationUnit, List<Declaration>> ComputeExternalReferences()
{
var typeReferenceCollector = new CLITypeReferenceCollector(Context.TypeMaps,
Context.Options);
typeReferenceCollector.Process(TranslationUnit);
var typeReferences = typeReferenceCollector.TypeReferences;
var imports = new Dictionary<TranslationUnit, List<Declaration>>();
foreach (var typeRef in typeReferences)
{
if (typeRef.Include.TranslationUnit == TranslationUnit)
continue;
if (typeRef.Include.File == TranslationUnit.FileName)
continue;
var include = typeRef.Include;
var typeRefUnit = include.TranslationUnit;
if (typeRefUnit != null && !typeRefUnit.IsDeclared)
continue;
if (!imports.ContainsKey(typeRefUnit))
imports[typeRefUnit] = new List<Declaration>();
imports[typeRefUnit].Add(typeRef.Declaration);
}
return imports;
}
public virtual bool NeedsExternalImports()
{
var imports = ComputeExternalReferences();
return imports.Keys.Count > 0;
}
public virtual void GenerateWildcardImports()
{
if (!NeedsExternalImports())
return;
foreach (var module in Options.Modules)
{
if (module == Options.SystemModule)
continue;
WriteLine($"import * as {module.LibraryName} from \"{module.LibraryName}\";");
}
}
public virtual void GenerateImports()
{
PushBlock(BlockKind.ForwardReferences);
var imports = ComputeExternalReferences();
foreach (var unit in imports)
{
string unitName = unit.Key.FileNameWithoutExtension;
if (Options.GenerateName != null)
unitName = Options.GenerateName(unit.Key);
var names = string.Join(", ", unit.Value.Select(d => d.Name));
WriteLine($"import {{{names}}} from \"{unitName}\";");
}
PopBlock(NewLineKind.BeforeNextBlock);
}
public override bool VisitNamespace(Namespace @namespace)
{
var isTopLevel = @namespace is TranslationUnit;
var generateNamespace = GenerateNamespaces;
if (generateNamespace)
{
PushBlock(BlockKind.Namespace, @namespace);
WriteLine(isTopLevel
? $"declare module \"{@namespace.TranslationUnit.Module.LibraryName}\""
: $"namespace {@namespace.Name}");
WriteOpenBraceAndIndent();
}
VisitDeclContext(@namespace);
if (generateNamespace)
{
UnindentAndWriteCloseBrace();
PopBlock(NewLineKind.BeforeNextBlock);
}
return true;
}
public override bool VisitClassDecl(Class @class)
{
if (!@class.IsGenerated || @class.IsIncomplete)
return false;
//if (@class.IsOpaque)
// return false;
PushBlock(BlockKind.Class, @class);
GenerateDeclarationCommon(@class);
GenerateClassSpecifier(@class);
if (@class.IsOpaque)
{
WriteLine(";");
return false;
}
NewLine();
WriteLine("{");
NewLine();
// Process the nested types.
Indent();
VisitDeclContext(@class);
Unindent();
GenerateClassConstructors(@class);
GenerateClassProperties(@class);
GenerateClassEvents(@class);
GenerateClassMethods(@class.Methods);
GenerateClassVariables(@class);
PushBlock(BlockKind.Fields);
GenerateClassFields(@class);
PopBlock();
WriteLine("}");
PopBlock(NewLineKind.BeforeNextBlock);
return true;
}
public void GenerateClassConstructors(Class @class)
{
if (@class.IsStatic)
return;
Indent();
var classNativeName = @class.Visit(CTypePrinter);
foreach (var ctor in @class.Constructors)
{
if (ASTUtils.CheckIgnoreMethod(ctor) || FunctionIgnored(ctor))
continue;
ctor.Visit(this);
}
Unindent();
}
public void GenerateClassFields(Class @class)
{
// Handle the case of struct (value-type) inheritance by adding the base
// properties to the managed value subtypes.
if (@class.IsValueType)
{
foreach (var @base in @class.Bases.Where(b => b.IsClass && b.Class.IsDeclared))
{
GenerateClassFields(@base.Class);
}
}
Indent();
// check for value types because some of the ignored fields may back properties;
// not the case for ref types because the NativePtr pattern is used there
foreach (var field in @class.Fields.Where(f => !ASTUtils.CheckIgnoreField(f)))
{
var property = @class.Properties.FirstOrDefault(p => p.Field == field);
if (property != null && !property.IsInRefTypeAndBackedByValueClassField())
{
field.Visit(this);
}
}
Unindent();
}
public void GenerateClassMethods(List<Method> methods)
{
if (methods.Count == 0)
return;
Indent();
var @class = (Class) methods[0].Namespace;
if (@class.IsValueType)
foreach (var @base in @class.Bases.Where(b => b.IsClass && !b.Class.Ignore))
GenerateClassMethods(@base.Class.Methods.Where(m => !m.IsOperator).ToList());
var staticMethods = new List<Method>();
foreach (var method in methods)
{
if (ASTUtils.CheckIgnoreMethod(method) || FunctionIgnored(method))
continue;
if (method.IsConstructor)
continue;
if (method.IsOperator)
continue;
if (method.IsStatic)
{
staticMethods.Add(method);
continue;
}
method.Visit(this);
}
foreach(var method in staticMethods)
method.Visit(this);
Unindent();
}
public void GenerateClassVariables(Class @class)
{
foreach (var variable in @class.Variables)
{
if (!variable.IsGenerated) continue;
variable.Visit(this);
}
}
public static string GetClassTemplateParameters(Class @class)
{
var @params = @class.TemplateParameters.OfType<TypeTemplateParameter>().Select(
p => !string.IsNullOrEmpty(p.Constraint) ? $"{p.Name} extends {p.Constraint}" : p.Name);
return $"<{string.Join(", ", @params)}>";
}
public string GetBaseClassTemplateParameters(BaseClassSpecifier baseClassSpec)
{
if (!(baseClassSpec.Type is TemplateSpecializationType templateSpecType))
throw new NotSupportedException();
var args = templateSpecType.Arguments.Select(arg =>
{
arg.Type.Type.TryGetClass(out var @class);
return @class;
});
return $"<{string.Join(", ", args.Select(c => c.Name))}>";
}
public override void GenerateClassSpecifier(Class @class)
{
if (@class.IsAbstract)
Write("abstract ");
Write(@class.IsInterface ? "interface" : "class");
Write($" {@class.Name}");
if (@class.IsDependent)
Write(GetClassTemplateParameters(@class));
if (!@class.IsStatic && @class.HasNonIgnoredBase)
{
var baseClassSpec = @class.Bases.First(bs => bs.Class == @class.BaseClass);
var baseClass = baseClassSpec.Class;
var needsQualifiedName = baseClass.TranslationUnit != @class.TranslationUnit;
var baseClassName = needsQualifiedName ? QualifiedIdentifier(baseClass) : baseClass.Name;
Write($" extends {baseClassName}");
if (baseClass.IsDependent)
Write($"{GetBaseClassTemplateParameters(baseClassSpec)}");
}
}
public void GenerateClassProperties(Class @class)
{
// Handle the case of struct (value-type) inheritance by adding the base
// properties to the managed value subtypes.
if (@class.IsValueType)
{
foreach (var @base in @class.Bases.Where(b => b.IsClass && b.Class.IsDeclared))
{
GenerateClassProperties(@base.Class);
}
}
Indent();
foreach (var prop in @class.Properties.Where(
prop => !ASTUtils.CheckIgnoreProperty(prop) && !TypeIgnored(prop.Type)))
{
if (prop.IsInRefTypeAndBackedByValueClassField())
{
prop.Field.Visit(this);
continue;
}
prop.Visit(this);
}
Unindent();
}
public virtual void GenerateIndexer(Property property)
{
throw new System.NotImplementedException();
}
public override string GenerateEnumSpecifier(Enumeration @enum)
{
Write($"enum {@enum.Name}");
return @enum.Name;
}
public override bool VisitFieldDecl(Field field)
{
PushBlock(BlockKind.Field, field);
GenerateDeclarationCommon(field);
var fieldType = field.Type.Visit(CTypePrinter);
WriteLine($"{fieldType} {field.Name};");
PopBlock();
return true;
}
public override bool VisitEvent(Event @event)
{
PushBlock(BlockKind.Event, @event);
GenerateDeclarationCommon(@event);
//WriteLine($"{@event.Name}: CppSharp.Signal;");
PopBlock(NewLineKind.BeforeNextBlock);
return true;
}
public override bool VisitProperty(Property property)
{
GenerateDeclarationCommon(property);
return base.VisitProperty(property);
}
public override bool VisitMethodDecl(Method method)
{
if (ASTUtils.CheckIgnoreMethod(method) || FunctionIgnored(method))
return false;
PushBlock(BlockKind.Method, method);
GenerateDeclarationCommon(method);
GenerateMethodSpecifier(method);
WriteLine(";");
PopBlock(NewLineKind.BeforeNextBlock);
return true;
}
public override void GenerateMethodSpecifier(Method method, MethodSpecifierKind? kind = null)
{
if (method.IsConstructor || method.IsDestructor ||
method.OperatorKind == CXXOperatorKind.Conversion ||
method.OperatorKind == CXXOperatorKind.ExplicitConversion)
{
Write($"{GetMethodIdentifier(method)}(");
GenerateMethodParameters(method);
Write($")");
return;
}
Write($"{GetMethodIdentifier(method)}(");
GenerateMethodParameters(method);
var returnType = method.ReturnType.Visit(CTypePrinter);
Write($"): {returnType}");
}
public override string GetMethodIdentifier(Function function,
TypePrinterContextKind context = TypePrinterContextKind.Managed)
{
if (function is Method method)
{
if (method.IsConstructor)
return "constructor";
}
return base.GetMethodIdentifier(function, context);
}
public override bool VisitTypedefNameDecl(TypedefNameDecl typedef)
{
if (!typedef.IsGenerated)
return false;
var functionType = typedef.Type as FunctionType;
if (functionType != null || typedef.Type.IsPointerTo(out functionType))
{
PushBlock(BlockKind.Typedef, typedef);
GenerateDeclarationCommon(typedef);
var @delegate = string.Format(CTypePrinter.VisitDelegate(functionType), typedef.Name);
WriteLine($"{@delegate};");
PopBlock(NewLineKind.BeforeNextBlock);
return true;
}
return false;
}
public override bool VisitFunctionDecl(Function function)
{
if (!function.IsGenerated || FunctionIgnored(function))
return false;
PushBlock(BlockKind.Function, function);
GenerateDeclarationCommon(function);
var retType = function.ReturnType.Visit(CTypePrinter);
Write($"export function {function.Name}(");
GenerateMethodParameters(function);
WriteLine($"): {retType};");
PopBlock();
return true;
}
public static bool FunctionIgnored(Function function)
{
return TypeIgnored(function.ReturnType.Type) ||
function.Parameters.Any(param => TypeIgnored(param.Type));
}
public static bool TypeIgnored(CppSharp.AST.Type type)
{
var desugared = type.Desugar();
var finalType = (desugared.GetFinalPointee() ?? desugared).Desugar();
Class @class;
return finalType.TryGetClass(out @class) && (@class.CompleteDeclaration == null && @class.IsIncomplete);
}
}
}

166
src/Generator/Generators/TS/TSTypePrinter.cs

@ -0,0 +1,166 @@ @@ -0,0 +1,166 @@
using System;
using System.Linq;
using CppSharp.AST;
using CppSharp.AST.Extensions;
using CppSharp.Generators.C;
namespace CppSharp.Generators.TS
{
public class TSTypePrinter : CppTypePrinter
{
public override string NamespaceSeparator => ".";
public override bool HasGlobalNamespacePrefix => false;
public override bool PrefixSpecialFunctions => true;
public TSTypePrinter(BindingContext context) : base(context)
{
PrintTypeModifiers = false;
}
public override string GlobalNamespace(Declaration declaration)
{
return declaration.TranslationUnit?.Module?.LibraryName;
}
public override TypePrinterResult GetDeclName(Declaration declaration, TypePrintScopeKind scope)
{
var result = base.GetDeclName(declaration, scope);
result.Type = result.Type.Replace("::", NamespaceSeparator);
return result;
}
public override TypePrinterResult VisitArrayType(ArrayType array, TypeQualifiers quals)
{
return $"{array.Type.Visit(this)}[]";
}
public override TypePrinterResult VisitBuiltinType(BuiltinType builtin, TypeQualifiers quals)
{
return VisitPrimitiveType(builtin.Type);
}
public override TypePrinterResult VisitPrimitiveType(PrimitiveType primitive, TypeQualifiers quals)
{
return VisitPrimitiveType(primitive);
}
public override TypePrinterResult VisitTypedefType(TypedefType typedef, TypeQualifiers quals)
{
if (typedef.Declaration.QualifiedOriginalName == "std::nullptr_t")
return VisitPrimitiveType(PrimitiveType.Null);
if (typedef.Declaration.Type.IsPrimitiveType())
return typedef.Declaration.Type.Visit(this);
return base.VisitTypedefType(typedef, quals);
}
public override TypePrinterResult VisitPrimitiveType(PrimitiveType primitive)
{
switch (primitive)
{
case PrimitiveType.Bool:
return "boolean";
case PrimitiveType.Void:
return "void";
case PrimitiveType.Char16:
case PrimitiveType.Char32:
case PrimitiveType.WideChar:
case PrimitiveType.Char:
case PrimitiveType.SChar:
case PrimitiveType.UChar:
case PrimitiveType.Short:
case PrimitiveType.UShort:
case PrimitiveType.Int:
case PrimitiveType.UInt:
case PrimitiveType.Long:
case PrimitiveType.ULong:
case PrimitiveType.LongLong:
return "number";
case PrimitiveType.ULongLong:
return "bigint";
case PrimitiveType.Half:
case PrimitiveType.Float:
case PrimitiveType.Double:
return "number";
case PrimitiveType.LongDouble:
case PrimitiveType.Float128:
case PrimitiveType.Int128:
case PrimitiveType.UInt128:
case PrimitiveType.IntPtr:
case PrimitiveType.UIntPtr:
case PrimitiveType.Null:
return "null";
case PrimitiveType.String:
return "string";
case PrimitiveType.Decimal:
return "number";
}
throw new NotSupportedException();
}
public override TypePrinterResult VisitPointerType(PointerType pointer, TypeQualifiers quals)
{
if (pointer.IsConstCharString())
return VisitPrimitiveType(PrimitiveType.String);
return base.VisitPointerType(pointer, quals);
}
public override TypePrinterResult VisitTagType(TagType tag, TypeQualifiers quals)
{
if (FindTypeMap(tag, out var result))
return result;
return tag.Declaration.Visit(this);
}
public override TypePrinterResult VisitTemplateSpecializationType(TemplateSpecializationType template,
TypeQualifiers quals)
{
if (!template.Desugared.Type.TryGetClass(out var @class))
return string.Empty;
var args = template.Arguments.Select(a => a.Type.Visit(this));
return $"{@class.Visit(this)}<{string.Join(", ", args)}>";
}
public override TypePrinterResult VisitParameter(Parameter param, bool hasName = true)
{
var oldParam = Parameter;
Parameter = param;
var result = param.QualifiedType.Visit(this);
result.Kind = GeneratorKind.TypeScript;
Parameter = oldParam;
var printName = hasName && !string.IsNullOrEmpty(param.Name);
if (!printName)
return result;
result.Name = param.Name;
/*
if (param.DefaultArgument != null && Options.GenerateDefaultValuesForArguments)
{
try
{
var expressionPrinter = new CSharpExpressionPrinter(this);
var defaultValue = expressionPrinter.VisitParameter(param);
return $"{result} = {defaultValue}";
}
catch (Exception)
{
var function = param.Namespace as Function;
Diagnostics.Warning($"Error printing default argument expression: " +
$"{function.QualifiedOriginalName}({param.OriginalName})");
}
}
*/
return $"{result}";
}
}
}

6
src/Generator/Generators/TypePrinter.cs

@ -13,6 +13,7 @@ namespace CppSharp.Generators @@ -13,6 +13,7 @@ namespace CppSharp.Generators
public StringBuilder NamePrefix { get; set; } = new StringBuilder();
public StringBuilder NameSuffix { get; set; } = new StringBuilder();
public TypeMap TypeMap { get; set; }
public GeneratorKind Kind { get; set; }
public TypePrinterResult(string type = "", string nameSuffix = "")
{
@ -35,7 +36,10 @@ namespace CppSharp.Generators @@ -35,7 +36,10 @@ namespace CppSharp.Generators
public override string ToString()
{
bool hasPlaceholder = Type.Contains("{0}");
if (Kind == GeneratorKind.TypeScript)
return $"{Name}{NameSuffix}: {Type}";
var hasPlaceholder = Type.Contains("{0}");
if (hasPlaceholder)
return string.Format(Type, $"{NamePrefix}{Name}{NameSuffix}");

1
src/Generator/Passes/CheckDuplicatedNamesPass.cs

@ -207,6 +207,7 @@ namespace CppSharp.Passes @@ -207,6 +207,7 @@ namespace CppSharp.Passes
case GeneratorKind.CPlusPlus:
case GeneratorKind.QuickJS:
case GeneratorKind.NAPI:
case GeneratorKind.TypeScript:
typePrinter = new CppTypePrinter(Context);
break;
case GeneratorKind.CLI:

3
tests2/ts/.gitignore vendored

@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
gen
*.js
*.map

32
tests2/ts/test.sh

@ -0,0 +1,32 @@ @@ -0,0 +1,32 @@
#!/usr/bin/env bash
set -e
dir=$(cd "$(dirname "$0")"; pwd)
rootdir="$dir/../.."
dotnet_configuration=Release
configuration=debug
platform=x64
jsinterp="$rootdir/deps/quickjs/qjs-debug"
red=`tput setaf 1`
green=`tput setaf 2`
reset=`tput sgr0`
generate=true
if [ $generate = true ]; then
echo "${green}Generating bindings${reset}"
dotnet $rootdir/bin/${dotnet_configuration}_${platform}/CppSharp.CLI.dll \
--gen=ts -I$dir/.. -I$rootdir/include -o $dir/gen -m tests $dir/../*.h
fi
echo "${green}Building generated binding files${reset}"
#make -C $dir/gen
echo
echo "${green}Typechecking generated binding files with tsc${reset}"
#tsc --noEmit --strict --noImplicitAny --strictNullChecks --strictFunctionTypes --noImplicitThis gen/*.d.ts
# echo "${green}Executing JS tests with QuickJS${reset}"
# cp $dir/gen/bin/$configuration/libtest.so $dir
# #cp $dir/gen/bin/$configuration/libtest.dylib $dir
# $jsinterp --std $dir/test.js

73
tests2/ts/test.ts

@ -0,0 +1,73 @@ @@ -0,0 +1,73 @@
import * as test from "tests";
function builtins()
{
eq(test.ReturnsVoid(), undefined)
eq(test.ReturnsBool(), true)
eq(test.PassAndReturnsBool(false), false)
eq(test.ReturnsNullptr(), null)
//eq(test.PassAndReturnsNullptr(null), null)
eq(test.ReturnsNullptr(), null)
eq(test.ReturnsChar (), ascii('a'));
eq(test.ReturnsSChar(), ascii('a'));
eq(test.ReturnsUChar(), ascii('a'));
eq(test.PassAndReturnsChar (ascii('a')), ascii('a'));
eq(test.PassAndReturnsSChar(ascii('b')), ascii('b'));
eq(test.PassAndReturnsUChar(ascii('c')), ascii('c'));
// TODO: add wchar_t tests
eq(test.ReturnsFloat (), 5.0);
eq(test.ReturnsDouble(), -5.0);
//eq(test.ReturnsLongDouble(), -5.0);
//floateq(test.PassAndReturnsFloat (1.32), 1.32);
floateq(test.PassAndReturnsDouble(1.32), 1.32);
//float(test.PassAndReturnsLongDouble(1.32), 1.32);
eq(test.ReturnsInt8 (), -5);
eq(test.ReturnsUInt8 (), 5);
eq(test.ReturnsInt16 (), -5);
eq(test.ReturnsUInt16(), 5);
eq(test.ReturnsInt32 (), -5);
eq(test.ReturnsUInt32(), 5);
eq(test.ReturnsInt64 (), -5n);
eq(test.ReturnsUInt64(), 5n);
const int8 = { min: -(2**7), max: (2**7) - 1 };
eq(test.PassAndReturnsInt8(int8.min), int8.min);
eq(test.PassAndReturnsInt8(int8.max), int8.max);
const uint8 = { min: 0, max: (2**8) - 1 };
eq(test.PassAndReturnsUInt8(uint8.min), uint8.min);
eq(test.PassAndReturnsUInt8(uint8.max), uint8.max);
const int16 = { min: -(2**15), max: (2**15) - 1 };
eq(test.PassAndReturnsInt16(int16.min), int16.min);
eq(test.PassAndReturnsInt16(int16.max), int16.max);
const uint16 = { min: 0, max: (2**16) - 1 };
eq(test.PassAndReturnsUInt16(uint16.min), uint16.min);
eq(test.PassAndReturnsUInt16(uint16.max), uint16.max);
const int32 = { min: -(2**31), max: (2**31) - 1 };
eq(test.PassAndReturnsInt32(int32.min), int32.min);
eq(test.PassAndReturnsInt32(int32.max), int32.max);
const uint32 = { min: 0, max: (2**32) - 1 };
eq(test.PassAndReturnsUInt32(uint32.min), uint32.min);
eq(test.PassAndReturnsUInt32(uint32.max), uint32.max);
const int64 = { min: BigInt(2**63) * -1n, max: BigInt(2**63) - 1n };
eq(test.PassAndReturnsInt64(int64.min), int64.min);
eq(test.PassAndReturnsInt64(int64.max), int64.max);
const uint64 = { min: BigInt(0), max: BigInt(2**64) - 1n };
eq(test.PassAndReturnsUInt64(uint64.min), uint64.min);
eq(test.PassAndReturnsUInt64(uint64.max), uint64.max);
}

13
tests2/ts/tsconfig.json

@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
{
"include": ["*.ts", "./gen/*.ts"],
"compilerOptions": {
"alwaysStrict": true, // Parse in strict mode and emit "use strict" for each source file.
"noImplicitAny": true,
"strictNullChecks": true,
"sourceMap": true,
"typeRoots": ["./gen"]
},
"typeAcquisition": {
"include": ["gen"]
}
}
Loading…
Cancel
Save