Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Gluecodium project Release Notes

## Unreleased
### Features:
* Dart: added support for type aliases (typedefs).

## 13.15.1
Release date 2025-06-05
### Bug-fixes:
Expand Down
4 changes: 3 additions & 1 deletion functional-tests/functional/dart/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ import "test/StaticIntMethods_test.dart" as StaticIntMethodsTests;
import "test/StaticStringMethods_test.dart" as StaticStringMethodsTests;
import "test/StructsWithConstants_test.dart" as StructsWithConstantsTests;
import "test/StructsWithMethods_test.dart" as StructsWithMethodsTests;
import "test/TypeAliases_test.dart" as TypeAliasesTests;

final _allTests = [
AsyncTests.main,
Expand Down Expand Up @@ -119,7 +120,8 @@ final _allTests = [
StaticIntMethodsTests.main,
StaticStringMethodsTests.main,
StructsWithConstantsTests.main,
StructsWithMethodsTests.main
StructsWithMethodsTests.main,
TypeAliasesTests.main
];

String _getLibraryPath(String nativeLibraryName) {
Expand Down
2 changes: 1 addition & 1 deletion functional-tests/functional/dart/pubspec.yaml.in
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: FunctionalDartTests
environment:
sdk: '>=2.12.0 <3.0.0'
sdk: '>=3.4.4 <4.0.0'
dependencies:
test:
functional:
Expand Down
55 changes: 55 additions & 0 deletions functional-tests/functional/dart/test/TypeAliases_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// -------------------------------------------------------------------------------------------------
// Copyright (C) 2016-2021 HERE Europe B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0
// License-Filename: LICENSE
//
// -------------------------------------------------------------------------------------------------

import "package:test/test.dart";
import "package:functional/test.dart";
import "../test_suite.dart";

final _testSuite = TestSuite("Type Aliases");

void main() {
_testSuite.test("Type alias to struct", () {
final result = StaticTypedefExampleStructTypedef("nonsense");

expect(result is StaticTypedefExampleStruct, isTrue);
expect(result.exampleString, "nonsense");
});
_testSuite.test("Type alias used by a function", () {
final result = StaticTypedef.returnIntTypedef(2);

expect(result is int, isTrue);
expect(result, 3);
});
_testSuite.test("Type alias points to a type alias", () {
final result = StaticTypedef.returnNestedIntTypedef(4);

expect(result is int, isTrue);
expect(result, 5);
});
_testSuite.test("Type alias from type collection", () {
final result = StaticTypedef.returnTypedefPointFromTypeCollection(
TypeCollectionPointTypedef(1.0, 3.0)
);

expect(result is TypeCollectionPoint, isTrue);
expect(result.x, 1.0);
expect(result.y, 3.0);
});
}
4 changes: 4 additions & 0 deletions functional-tests/functional/input/lime/StaticTypedef.lime
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ class StaticTypedef {
// Example struct
struct ExampleStruct {
exampleString: String = ""

@Skip(Dart)
field constructor()
field constructor(exampleString)
}
typealias IntTypedef = Int
typealias NestedIntTypedef = IntTypedef
Expand Down
25 changes: 25 additions & 0 deletions functional-tests/functional/input/lime/VisibilityInternal.lime
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,31 @@ struct PublicStructWithNonDefaultInternalField {
publicField: Boolean
}

@Skip(Java, Kotlin, Swift)
@Internal
class DartInternalClassWithInternalTypedef {
@Internal
typealias SomeStringToIntMap = Map<String, Int>

@Internal
typealias SomeStringArray = List<String>

property numbers: SomeStringToIntMap
property labels: SomeStringArray
}

@Skip(Java, Kotlin, Swift)
class SomeDartClassThatUsesInternal {
@Internal
typealias ListOfInternals = List<DartInternalClassWithInternalTypedef>

@Internal
fun add_entity(
// The entity to add.
entity: DartInternalClassWithInternalTypedef
)
}

@Internal
class InternalClassWithStaticProperty {
static property fooBar: String
Expand Down
29 changes: 29 additions & 0 deletions functional-tests/functional/input/src/cpp/VisibilityInternal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
//
// -------------------------------------------------------------------------------------------------

#include "test/DartInternalClassWithInternalTypedef.h"
#include "test/DartInternalElements.h"
#include "test/DartInternalElementsRev.h"
#include "test/DartPublicElements.h"
Expand All @@ -26,6 +27,34 @@

namespace test
{

class SomeImplOfDartInternalClassWithInternalTypedef : public DartInternalClassWithInternalTypedef {
public:
SomeImplOfDartInternalClassWithInternalTypedef() = default;
~SomeImplOfDartInternalClassWithInternalTypedef() override = default;

public:
::test::DartInternalClassWithInternalTypedef::SomeStringToIntMap get_numbers() const override {
return m_numbers;
}

void set_numbers(const ::test::DartInternalClassWithInternalTypedef::SomeStringToIntMap& value) override {
m_numbers = value;
}

::test::DartInternalClassWithInternalTypedef::SomeStringArray get_labels() const override {
return m_labels;
}

void set_labels(const ::test::DartInternalClassWithInternalTypedef::SomeStringArray& value) override {
m_labels = value;
}

private:
::test::DartInternalClassWithInternalTypedef::SomeStringToIntMap m_numbers{};
::test::DartInternalClassWithInternalTypedef::SomeStringArray m_labels{};
};

std::shared_ptr<InternalClassWithFunctions>
InternalClassWithFunctions::make() {
return {};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ internal class DartGenerator : Generator {

val generatedFiles =
dartFilteredModel.topElements.flatMap {
listOfNotNull(
listOf(
generateDart(
it, dartResolvers, dartNameResolver, listOf(importsCollector, declarationImportsCollector),
exportsCollector, typeRepositoriesCollector, predicatesMap, descendantInterfaces,
Expand Down Expand Up @@ -231,8 +231,8 @@ internal class DartGenerator : Generator {
predicates: Map<String, (Any) -> Boolean>,
descendantInterfaces: Map<String, List<LimeInterface>>,
asyncHelpers: DartAsyncHelpers.AsyncHelpersGroup?,
): GeneratedFile? {
val contentTemplateName = selectTemplate(rootElement) ?: return null
): GeneratedFile {
val contentTemplateName = selectTemplate(rootElement)

val packagePath = rootElement.path.head.joinToString(separator = "/")
val fileName = dartNameResolver.resolveFileName(rootElement)
Expand All @@ -241,7 +241,7 @@ internal class DartGenerator : Generator {

val isInternal = predicates["isInternal"]!!

val allTypes = LimeTypeHelper.getAllTypes(rootElement).filterNot { it is LimeTypeAlias }
val allTypes = LimeTypeHelper.getAllTypes(rootElement)
val nonExternalTypes = allTypes.filter { it.external?.dart == null }
val allSymbols = nonExternalTypes.filterNot { isInternal(it) }
if (allSymbols.isNotEmpty()) {
Expand All @@ -258,11 +258,13 @@ internal class DartGenerator : Generator {
val optimizedLists = OptimizedListsCollector().getAllOptimizedLists(rootElement)

val imports = importCollectors.flatMap { it.collectImports(rootElement) }
val nonConversionImports = imports.filterNot { it.filePath.endsWith("__conversion") }
val content =
TemplateEngine.render(
"dart/DartFile",
mapOf(
"imports" to imports.distinct().sorted().filterNot { it.filePath.endsWith(filePath) },
"nonConversionImports" to nonConversionImports.distinct().sorted().filterNot { it.filePath.endsWith(filePath) },
"model" to rootElement,
"contentTemplate" to contentTemplateName,
"libraryName" to libraryName,
Expand Down Expand Up @@ -563,7 +565,7 @@ internal class DartGenerator : Generator {
is LimeEnumeration -> "dart/DartEnumeration"
is LimeException -> "dart/DartException"
is LimeLambda -> "dart/DartLambda"
is LimeTypeAlias -> null
is LimeTypeAlias -> "dart/DartTypeAlias"
else -> throw GluecodiumExecutionException(
"Unsupported top-level element: " +
limeElement::class.java.name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,16 @@ internal class DartImportResolver(
limeType: LimeType,
skipHelpers: Boolean = false,
): List<DartImport> {
val actualType = limeType.actualType
when (actualType) {
is LimeBasicType -> return resolveBasicTypeImports(actualType)
is LimeGenericType -> return resolveGenericTypeImports(actualType)
when (limeType) {
is LimeBasicType -> return resolveBasicTypeImports(limeType)
is LimeGenericType -> return resolveGenericTypeImports(limeType)
}

val externalImport = resolveExternalImport(actualType, IMPORT_PATH_NAME, useAlias = true)
val externalImport = resolveExternalImport(limeType, IMPORT_PATH_NAME, useAlias = true)
return when {
externalImport == null -> listOf(createImport(actualType))
externalImport == null -> listOf(createImport(limeType))
skipHelpers -> listOf(externalImport)
else -> listOf(createImport(actualType), externalImport)
else -> listOf(createImport(limeType), externalImport)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ internal class DartImportsCollector(importsResolver: ImportsResolver<DartImport>
collectTypeRefImports = true,
collectValueImports = true,
parentTypeFilter = { true },
collectTypeAliasImports = true,
) {
override fun collectParentTypeRefs(limeContainer: LimeContainerWithInheritance) =
when (limeContainer) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ import com.here.gluecodium.model.lime.LimeReturnType
import com.here.gluecodium.model.lime.LimeSet
import com.here.gluecodium.model.lime.LimeStruct
import com.here.gluecodium.model.lime.LimeType
import com.here.gluecodium.model.lime.LimeTypeAlias
import com.here.gluecodium.model.lime.LimeTypeHelper
import com.here.gluecodium.model.lime.LimeTypeRef
import com.here.gluecodium.model.lime.LimeValue
Expand Down Expand Up @@ -83,7 +82,6 @@ internal class DartNameResolver(
is LimeValue -> resolveValue(element)
is LimeGenericType -> resolveGenericType(element)
is LimeTypeRef -> resolveTypeRefName(element)
is LimeTypeAlias -> resolveName(element.typeRef)
is LimeType -> resolveTypeName(element)
is LimeNamedElement -> getPlatformName(element)
else ->
Expand Down Expand Up @@ -291,12 +289,12 @@ internal class DartNameResolver(
ignoreNullability: Boolean = false,
): String {
val typeName = resolveName(limeTypeRef.type)
val importPath = limeTypeRef.type.actualType.external?.dart?.get(IMPORT_PATH_NAME)
val importPath = limeTypeRef.type.external?.dart?.get(IMPORT_PATH_NAME)
val alias =
when {
importPath != null -> computeAlias(importPath)
ignoreDuplicates -> null
duplicateNames.contains(typeName) -> limeTypeRef.type.actualType.path.head.joinToString("_")
duplicateNames.contains(typeName) -> limeTypeRef.type.path.head.joinToString("_")
else -> null
}
val suffix = if (limeTypeRef.isNullable && !ignoreNullability) "?" else ""
Expand Down Expand Up @@ -339,7 +337,7 @@ internal class DartNameResolver(
private fun buildDuplicateNames() =
limeReferenceMap.values
.filterIsInstance<LimeType>()
.filterNot { it is LimeTypeAlias || it is LimeGenericType || it is LimeBasicType }
.filterNot { it is LimeGenericType || it is LimeBasicType }
.filter { it.external?.dart == null }
.groupBy { resolveTypeName(it) }
.filterValues { it.size > 1 }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ abstract class {{resolveName}}{{!!
{{/ifPredicate}}
}

{{#typeAliases}}
{{>dart/DartTypeAlias}}
{{/typeAliases}}
{{#enumerations}}
{{>dart/DartEnumeration}}
{{/enumerations}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,16 @@
!}}
{{#if copyrightHeader}}{{prefix copyrightHeader "// "}}{{/if}}

{{#instanceOf model "LimeTypeAlias"}}
{{#nonConversionImports}}
{{>dart/DartImport}}
{{/nonConversionImports}}
{{/instanceOf}}
{{#notInstanceOf model "LimeTypeAlias"}}
{{#imports}}
{{>dart/DartImport}}
{{/imports}}
{{/notInstanceOf}}

{{#model}}
{{include contentTemplate}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ abstract class {{resolveName}}{{!!
{{/ifPredicate}}
}

{{#typeAliases}}
{{>dart/DartTypeAlias}}
{{/typeAliases}}
{{#enumerations}}
{{>dart/DartEnumeration}}
{{/enumerations}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
!}}
name: {{libraryName}}
environment:
sdk: '>=2.12.0 <3.0.0'
sdk: '>=3.4.4 <4.0.0'
dependencies:
ffi:
intl:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ class {{resolveName}}{{#if external.dart.converter}}Internal{{/if}} {
}
{{/unlessPredicate}}

{{#typeAliases}}
{{>dart/DartTypeAlias}}
{{/typeAliases}}
{{#enumerations}}
{{>dart/DartEnumeration}}
{{/enumerations}}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{{!!
!
! Copyright (C) 2016-2021 HERE Europe B.V.
!
! Licensed under the Apache License, Version 2.0 (the "License");
! you may not use this file except in compliance with the License.
! You may obtain a copy of the License at
!
! http://www.apache.org/licenses/LICENSE-2.0
!
! Unless required by applicable law or agreed to in writing, software
! distributed under the License is distributed on an "AS IS" BASIS,
! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
! See the License for the specific language governing permissions and
! limitations under the License.
!
! SPDX-License-Identifier: Apache-2.0
! License-Filename: LICENSE
!
!}}
{{>dart/DartDocumentation}}{{>dart/DartAttributes}}
typedef {{resolveName}} = {{resolveName typeRef}};
Loading