.NET Bindings: Fix netmaker and net_basetypes

This commit makes a few misc. fixes to netmaker and net_basetypes
- Renamed css.uno.Exception to css.uno.UnoException to avoid name
  conflicts with System.Exception
- Added a new css.uno.Any constructor and setValue function that
  deduces the type of the any from given object at runtime
- Changed the AnyTests unit tests to match changes made to css.uno.Any
- Removed the in keyword from UNO 'in' parameters. Was a premature
  optimisation that might have a negative effect for certain types.
- Generated struct and exception field members were not marked public
  earlier by accident, fixed.
- Generted struct and exception constructors had parameters in order
  opposite to expected, fixed.
- Generated services tried to instantiate the interface, not the
  service earlier, fixed.

Change-Id: Ia63f9db469db13a5d01617617095b8f568b39c72
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171706
Tested-by: Jenkins
Reviewed-by: Hossein <hossein@libreoffice.org>
This commit is contained in:
RMZeroFour 2024-08-09 21:57:34 +05:30 committed by Hossein
parent 14b7b50701
commit 641d082c44
5 changed files with 52 additions and 47 deletions

View file

@ -55,7 +55,7 @@ const std::unordered_map<OString, OString> s_baseTypes{
{ "void"_ostr, "void"_ostr },
{ "type"_ostr, "System.Type"_ostr },
{ "any"_ostr, "com.sun.star.uno.Any"_ostr },
{ "com.sun.star.uno.Exception"_ostr, "com.sun.star.uno.Exception"_ostr },
{ "com.sun.star.uno.Exception"_ostr, "com.sun.star.uno.UnoException"_ostr },
{ "com.sun.star.uno.XInterface"_ostr, "com.sun.star.uno.IQueryInterface"_ostr },
};
@ -342,15 +342,15 @@ void NetProducer::producePlainStruct(std::string_view name,
rtl::Reference<unoidl::PlainStructTypeEntity> ref(
dynamic_cast<unoidl::PlainStructTypeEntity*>(baseEntity.get()));
for (const auto& member : ref->getDirectMembers())
baseFields.emplace_back(member);
baseFields.insert(baseFields.begin(), ref->getDirectMembers().begin(),
ref->getDirectMembers().end());
baseTypeName = ref->getDirectBase();
}
}
std::vector<unoidl::PlainStructTypeEntity::Member> allFields(entity->getDirectMembers());
allFields.insert(allFields.end(), baseFields.begin(), baseFields.end());
allFields.insert(allFields.begin(), baseFields.begin(), baseFields.end());
file.beginLine().append("public ").append(getSafeIdentifier(typeName)).append("(");
separatedForeach(
@ -384,6 +384,7 @@ void NetProducer::producePlainStruct(std::string_view name,
if (anno == "deprecated")
file.beginLine().append("[System.Obsolete]").endLine();
file.beginLine()
.append("public ")
.append(getNetName(member.type))
.append(" ")
.append(getSafeIdentifier(member.name))
@ -475,6 +476,7 @@ void NetProducer::producePolyStruct(
if (anno == "deprecated")
file.beginLine().append("[System.Obsolete]").endLine();
file.beginLine()
.append("public ")
.append(member.parameterized ? u2b(member.type) : getNetName(member.type))
.append(" ")
.append(getSafeIdentifier(member.name))
@ -549,15 +551,15 @@ void NetProducer::produceException(std::string_view name,
rtl::Reference<unoidl::ExceptionTypeEntity> ref(
dynamic_cast<unoidl::ExceptionTypeEntity*>(baseEntity.get()));
for (const auto& member : ref->getDirectMembers())
baseFields.emplace_back(member);
baseFields.insert(baseFields.begin(), ref->getDirectMembers().begin(),
ref->getDirectMembers().end());
baseTypeName = ref->getDirectBase();
}
}
std::vector<unoidl::ExceptionTypeEntity::Member> allFields(entity->getDirectMembers());
allFields.insert(allFields.end(), baseFields.begin(), baseFields.end());
allFields.insert(allFields.begin(), baseFields.begin(), baseFields.end());
file.beginLine().append("public ").append(getSafeIdentifier(typeName)).append("(");
separatedForeach(
@ -591,6 +593,7 @@ void NetProducer::produceException(std::string_view name,
if (anno == "deprecated")
file.beginLine().append("[System.Obsolete]").endLine();
file.beginLine()
.append("public ")
.append(getNetName(member.type))
.append(" ")
.append(getSafeIdentifier(member.name))
@ -732,7 +735,6 @@ void NetProducer::produceInterface(std::string_view name,
switch (p.direction)
{
case Dir::DIRECTION_IN:
file.append("in ");
break;
case Dir::DIRECTION_OUT:
file.append("out ");
@ -903,7 +905,7 @@ void NetProducer::produceService(
file.beginLine()
.append("public static ")
.append(returnType)
.append(" create(in com.sun.star.uno.XComponentContext ctx)")
.append(" create(com.sun.star.uno.XComponentContext ctx)")
.endLine()
.beginBlock();
@ -920,7 +922,7 @@ void NetProducer::produceService(
.append(" srv = (")
.append(returnType)
.append(")mcf.createInstanceWithContext(\"")
.append(returnType)
.append(name)
.append("\", ctx);")
.endLine()
.beginLine()
@ -949,7 +951,7 @@ void NetProducer::produceService(
.beginLine()
.append(
"throw new com.sun.star.uno.DeploymentException(\"Could not create service ")
.append(returnType)
.append(name)
.append(" from given XComponentContext\", ctx);")
.endLine()
.endBlock();
@ -968,7 +970,7 @@ void NetProducer::produceService(
.append(returnType)
.append(" ")
.append(getSafeIdentifier(ctor.name))
.append("(in com.sun.star.uno.XComponentContext ctx");
.append("(com.sun.star.uno.XComponentContext ctx");
if (!ctor.parameters.empty())
file.append(", ");
separatedForeach(
@ -991,7 +993,7 @@ void NetProducer::produceService(
.append(" srv = (")
.append(returnType)
.append(")mcf.createInstanceWithArgumentsAndContext(\"")
.append(returnType)
.append(name)
.append("\", ");
if (restParam)
{
@ -1006,7 +1008,7 @@ void NetProducer::produceService(
file.append("new com.sun.star.uno.Any[] { ");
separatedForeach(ctor.parameters, [&file]() { file.append(", "); },
[&file](const auto& p) {
file.append("com.sun.star.uno.Any.with(")
file.append("new com.sun.star.uno.Any(")
.append(getSafeIdentifier(p.name))
.append(")");
});
@ -1018,7 +1020,7 @@ void NetProducer::produceService(
{
file.beginLine()
.append("catch (")
.append(e)
.append(getNetName(e))
.append(")")
.endLine()
.beginBlock()
@ -1035,7 +1037,7 @@ void NetProducer::produceService(
.beginLine()
.append(
"throw new com.sun.star.uno.DeploymentException(\"Could not create service ")
.append(returnType)
.append(name)
.append(" from given XComponentContext\", ctx);")
.endLine()
.endBlock();
@ -1082,7 +1084,7 @@ void NetProducer::produceSingleton(
file.beginLine()
.append("public static ")
.append(getNetName(entity->getBase()))
.append(" get(in com.sun.star.uno.XComponentContext ctx)")
.append(" get(com.sun.star.uno.XComponentContext ctx)")
.endLine()
.beginBlock();

View file

@ -11,9 +11,9 @@ $(eval $(call gb_DotnetLibrary_DotnetLibrary,net_basetypes,$(gb_DotnetLibrary_CS
$(eval $(call gb_DotnetLibrary_add_sources,net_basetypes,\
net_ure/source/basetypes/Any \
net_ure/source/basetypes/BoundAttribute \
net_ure/source/basetypes/Exception \
net_ure/source/basetypes/IQueryInterface \
net_ure/source/basetypes/RaisesAttribute \
net_ure/source/basetypes/UnoException \
net_ure/source/basetypes/UnoGeneratedAttribute \
))

View file

@ -15,7 +15,7 @@ public class AnyTests
}
[Test]
[Description("Tests if the Any(type, value) constructor throws on invalid args")]
[Description("Tests if the Any constructor throws on invalid args")]
public void ctor_RejectsInvalidParams()
{
Assert.That(() => new Any(null, 10), Throws.ArgumentNullException);
@ -24,37 +24,39 @@ public class AnyTests
}
[Test]
[Description("Tests if Any.with<T>(value) throws on invalid args")]
[Description("Tests if Any.with throws on invalid args")]
public void with_RejectsInvalidParams()
{
Assert.That(() => new Any(typeof(Any), Any.VOID), Throws.ArgumentException);
Assert.That(() => Any.with<Any>(Any.VOID), Throws.ArgumentException);
Assert.That(() => Any.with<int>(null), Throws.ArgumentException);
}
[Test]
[Description("Tests if Any.equals(other) and Any.operator== returns true for identical values")]
[Description("Tests if Any.equals and Any.operator== returns true for identical values")]
public void equals_ReturnsTrueForSame()
{
Assert.That(Any.VOID == new Any(typeof(void), null), Is.True);
Assert.That(Any.with(10).equals(new Any(typeof(int), 10)), Is.True);
Assert.That(new Any(typeof(bool), false).Equals(Any.with(false)), Is.True);
Assert.That(Any.with<int>(10).equals(new Any(typeof(int), 10)), Is.True);
Assert.That(new Any(typeof(bool), false).Equals(new Any(false)), Is.True);
}
[Test]
[Description("Tests if Any.equals(other) and Any.operator== returns false for different values")]
[Description("Tests if Any.equals and Any.operator== returns false for different values")]
public void equals_ReturnsTrueForDifferent()
{
Assert.That(Any.VOID == Any.with(10), Is.False);
Assert.That(Any.VOID != Any.with(10), Is.True);
Assert.That(Any.with(10).equals(Any.with(20)), Is.False);
Assert.That(Any.with(true).Equals(Any.with(1)), Is.False);
Assert.That(Any.VOID == Any.with<int>(10), Is.False);
Assert.That(Any.VOID != new Any(10), Is.True);
Assert.That(Any.with<int>(10).equals(new Any(20)), Is.False);
Assert.That(new Any(typeof(bool), true).Equals(Any.with<int>(1)), Is.False);
}
[Test]
[Description("Tests if Any.hasValue() returns false for Any.VOID and true for all else")]
public void hasValue_ReturnsFalseOnlyForVOID()
[Description("Tests if Any.hasValue() returns false for Any.VOID and equivalent values")]
public void hasValue_ReturnsFalseForVOIDValues()
{
Assert.That(Any.VOID.hasValue, Is.False);
Assert.That(Any.with(10).hasValue, Is.True);
Assert.That(new Any(null).hasValue, Is.False);
Assert.That(Any.with<int>(10).hasValue, Is.True);
Assert.That(new Any(typeof(string), "hello").hasValue, Is.True);
}
@ -68,7 +70,10 @@ public class AnyTests
any.setValue(typeof(string), "hello");
Assert.That(any.Type, Is.EqualTo(typeof(string)));
Assert.That(any.Value, Is.EqualTo("hello"));
any.setValue(false);
any.setValue(3.14);
Assert.That(any.Type, Is.EqualTo(typeof(double)));
Assert.That(any.Value, Is.EqualTo(3.14));
any.setValue<bool>(false);
Assert.That(any.Type, Is.EqualTo(typeof(bool)));
Assert.That(any.Value, Is.EqualTo(false));
}
@ -77,7 +82,7 @@ public class AnyTests
[Description("Tests if Any.setValue(type, value) method throws on invalid args")]
public void setValue_RejectsInvalidParams()
{
Any any = Any.with(10);
Any any = new Any(10);
Assert.That(() => any.setValue(null, 10), Throws.ArgumentNullException);
Assert.That(() => any.setValue(Any.VOID), Throws.ArgumentException);
Assert.That(() => any.setValue(typeof(int), null), Throws.ArgumentException);
@ -88,13 +93,13 @@ public class AnyTests
public void GetHashCode_ReturnsTrueForSame()
{
Assert.That(Any.VOID.GetHashCode() == Any.VOID.GetHashCode(), Is.True);
Assert.That(Any.with(10).GetHashCode() == Any.with(10).GetHashCode(), Is.True);
Assert.That(new Any(10).GetHashCode() == Any.with<int>(10).GetHashCode(), Is.True);
}
[Test]
[Description("Tests if Any.GetHashCode() returns different hash for different values")]
public void GetHashCode_ReturnsTrueForDifferent()
{
Assert.That(Any.VOID.GetHashCode() == Any.with(10).GetHashCode(), Is.False);
Assert.That(Any.VOID.GetHashCode() == Any.with<int>(10).GetHashCode(), Is.False);
}
}

View file

@ -18,7 +18,8 @@ namespace com.sun.star.uno
public Object Value { get; private set; }
public Any(Type type, object value) => setValue(type, value);
public static Any with<T>(T value) => new Any(typeof(T), value);
public Any(object value) : this(value?.GetType() ?? typeof(void), value) { }
public static Any with<T>(object value) => new Any(typeof(T), value);
public bool hasValue() => Type != typeof(void);
@ -37,7 +38,8 @@ namespace com.sun.star.uno
Type = type;
Value = value;
}
public void setValue<T>(T value) => setValue(typeof(T), value);
public void setValue(object value) => setValue(value.GetType(), value);
public void setValue<T>(object value) => setValue(typeof(T), value);
public bool equals(Any other)
{

View file

@ -10,16 +10,12 @@ using System;
namespace com.sun.star.uno
{
public class Exception : System.Exception
public class UnoException : Exception
{
public new string Message { get; set; }
public IQueryInterface Context { get; set; }
public Exception() { }
public Exception(string Message, IQueryInterface Context)
{
this.Message = Message;
this.Context = Context;
}
public UnoException() { }
public UnoException(string Message, IQueryInterface Context)
: base(Message) => this.Context = Context;
}
}