Browse Source

Implement support for properties in Emscripten generator.

pull/1932/head
tritao 2 months ago
parent
commit
83f2c4d786
  1. 2
      .github/workflows/main.yml
  2. 14
      src/Generator/Driver.cs
  3. 31
      src/Generator/Generators/Emscripten/EmscriptenSources.cs
  4. 22
      tests/Classes.h
  5. 9
      tests/emscripten/test.mjs
  6. 4
      tests/emscripten/test.sh

2
.github/workflows/main.yml

@ -37,7 +37,7 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Setup emsdk - name: Setup emsdk
uses: mymindstorm/setup-emsdk@v11 uses: mymindstorm/setup-emsdk@v14
with: with:
version: ${{ env.EMSCRIPTEN_VERSION }} version: ${{ env.EMSCRIPTEN_VERSION }}
actions-cache-folder: emsdk-cache-${{ runner.os }} actions-cache-folder: emsdk-cache-${{ runner.os }}

14
src/Generator/Driver.cs

@ -252,7 +252,12 @@ namespace CppSharp
passes.AddPass(new CleanInvalidDeclNamesPass()); passes.AddPass(new CleanInvalidDeclNamesPass());
passes.AddPass(new FastDelegateToDelegatesPass()); passes.AddPass(new FastDelegateToDelegatesPass());
passes.AddPass(new FieldToPropertyPass());
if (Options.GeneratorKind != GeneratorKind.Emscripten)
{
passes.AddPass(new FieldToPropertyPass());
}
passes.AddPass(new CheckIgnoredDeclsPass()); passes.AddPass(new CheckIgnoredDeclsPass());
passes.AddPass(new CheckEnumsPass()); passes.AddPass(new CheckEnumsPass());
passes.AddPass(new MakeProtectedNestedTypesPublicPass()); passes.AddPass(new MakeProtectedNestedTypesPublicPass());
@ -283,9 +288,14 @@ namespace CppSharp
passes.AddPass(new CheckDuplicatedNamesPass()); passes.AddPass(new CheckDuplicatedNamesPass());
if (Options.IsCLIGenerator || Options.IsCSharpGenerator) if (Options.IsCLIGenerator || Options.IsCSharpGenerator
|| Options.GeneratorKind.ID is GeneratorKind.Emscripten_ID)
{ {
passes.RenameDeclsUpperCase(RenameTargets.Any & ~RenameTargets.Parameter); passes.RenameDeclsUpperCase(RenameTargets.Any & ~RenameTargets.Parameter);
}
if (Options.IsCLIGenerator || Options.IsCSharpGenerator)
{
passes.AddPass(new CheckKeywordNamesPass()); passes.AddPass(new CheckKeywordNamesPass());
} }

31
src/Generator/Generators/Emscripten/EmscriptenSources.cs

@ -117,11 +117,6 @@ namespace CppSharp.Generators.Emscripten
} }
} }
public override bool VisitProperty(Property property)
{
return true;
}
public override bool VisitMethodDecl(Method method) public override bool VisitMethodDecl(Method method)
{ {
Indent(); Indent();
@ -130,9 +125,33 @@ namespace CppSharp.Generators.Emscripten
return ret; return ret;
} }
public override bool VisitProperty(Property property)
{
if (property.Field != null)
return property.Field.Visit(this);
if (!property.GetMethod.IsConst)
{
Console.WriteLine($"Cannot bind non-const property getter method: {property.GetMethod.QualifiedOriginalName}");
return false;
}
var @class = property.Namespace as Class;
Indent();
Write($".property(\"{property.Name}\", &{@class.QualifiedOriginalName}::{property.GetMethod.OriginalName}");
if (property.HasSetter)
Write($", &{@class.QualifiedOriginalName}::{property.SetMethod.OriginalName}");
WriteLine(")");
Unindent();
return true;
}
public override bool VisitFieldDecl(Field field) public override bool VisitFieldDecl(Field field)
{ {
WriteLineIndent($".field(\"{field.Name}\", &{field.Class.QualifiedOriginalName}::{field.OriginalName})"); WriteLineIndent($".property(\"{field.Name}\", &{field.Class.QualifiedOriginalName}::{field.OriginalName})");
return true; return true;
} }

22
tests/Classes.h

@ -6,8 +6,8 @@ class Class
{ {
public: public:
void ReturnsVoid() {} void ReturnsVoid() {}
int ReturnsInt() { return 0; } int ReturnsInt() const { return 0; }
// Class* PassAndReturnsClassPtr(Class* obj) { return obj; } Class* PassAndReturnsClassPtr(Class* obj) { return obj; }
}; };
class ClassWithField class ClassWithField
@ -18,7 +18,21 @@ public:
{ {
} }
int Field; int Field;
int ReturnsField() { return Field; } int ReturnsField() const { return Field; }
};
class ClassWithProperty
{
public:
ClassWithProperty()
: Field(10)
{
}
int GetField() const { return Field; }
void SetField(int value) { Field = value; }
private:
int Field;
}; };
class ClassWithOverloads class ClassWithOverloads
@ -41,4 +55,4 @@ class ClassWithExternalInheritance : public ClassFromAnotherUnit
}; };
// void FunctionPassClassByRef(Class* klass) { } // void FunctionPassClassByRef(Class* klass) { }
// Class* FunctionReturnsClassByRef() { return new Class(); } // Class* FunctionReturnsClassByRef() { return new Class(); }

9
tests/emscripten/test.mjs

@ -111,7 +111,14 @@ function classes() {
var classWithField = new test.ClassWithField(); var classWithField = new test.ClassWithField();
eq(classWithField.ReturnsField(), 10); eq(classWithField.ReturnsField(), 10);
//eq(classWithField.Field, 10); eq(classWithField.Field, 10);
classWithField.Field = 20;
eq(classWithField.ReturnsField(), 20);
var classWithProperty = new test.ClassWithProperty();
eq(classWithProperty.Field, 10);
classWithProperty.Field = 20;
eq(classWithProperty.Field, 20);
} }
builtins(); builtins();

4
tests/emscripten/test.sh

@ -38,8 +38,8 @@ generate=true
if [ $generate = true ]; then if [ $generate = true ]; then
echo "${green}Generating bindings${reset}" echo "${green}Generating bindings${reset}"
dotnet $rootdir/bin/${dotnet_configuration}/CppSharp.CLI.dll \ dotnet $rootdir/bin/${dotnet_configuration}_${platform}/CppSharp.CLI.dll \
--gen=emscripten --platform=emscripten --arch=wasm32 \ --gen=emscripten --platform=emscripten --arch=wasm32 --property=keywords \
-I$dir/.. -I$rootdir/include -o $dir/gen -m tests $dir/../*.h -I$dir/.. -I$rootdir/include -o $dir/gen -m tests $dir/../*.h
fi fi

Loading…
Cancel
Save