Skip to content

Commit

Permalink
Generate type aliases in Dart
Browse files Browse the repository at this point in the history
Added dedicated DartTypeAlias template, as type aliases (typedefs) are now
supported in Dart language (since Dart version 2.13). Updated other Dart
tempates and resolvers to treat type aliases as a normal type, instead of
skipping it through to the target type.

Added/updated related smoke and functional tests.

Unrelated smoke tests are updated in a separate commit.

Resolves: #907
Signed-off-by: Daniel Kamkha <[email protected]>
  • Loading branch information
DanielKamkha committed Nov 10, 2021
1 parent 607381c commit e37a9d5
Show file tree
Hide file tree
Showing 16 changed files with 145 additions and 41 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/functional-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ jobs:
- name: Install Dart SDK
run: |
DART_RELEASE_CHANNEL=stable
DART_VERSION=2.12.0
DART_VERSION=2.13.3
wget -nv https://storage.googleapis.com/dart-archive/channels/${DART_RELEASE_CHANNEL}/release/${DART_VERSION}/linux_packages/dart_${DART_VERSION}-1_amd64.deb
sudo apt -y install ./dart_${DART_VERSION}-1_amd64.deb
- name: Build and run functional tests
Expand Down Expand Up @@ -276,8 +276,8 @@ jobs:
uses: actions/cache@v2
with:
path: ~/dart_sdk
key: ${{ runner.os }}-dart-2.12.0-stable
restore-keys: ${{ runner.os }}-dart-2.12.0-stable
key: ${{ runner.os }}-dart-2.13.3-stable
restore-keys: ${{ runner.os }}-dart-2.13.3-stable
- name: Install CMake
uses: jwlawson/[email protected]
with:
Expand All @@ -289,7 +289,7 @@ jobs:
export DART_ROOT=${HOME}/dart_sdk
export DART_BIN=${DART_ROOT}/bin
export PATH=${PATH}:${PWD}/depot_tools:${DART_BIN}
DART_VERSION=2.12.0
DART_VERSION=2.13.3
if [ ! -d "${DART_ROOT}/bin" ]; then
sudo apt install -y python2
sudo update-alternatives --install /usr/bin/python python /usr/bin/python2 1
Expand Down Expand Up @@ -364,7 +364,7 @@ jobs:
- name: Install Dart SDK
run: |
DART_RELEASE_CHANNEL=stable
DART_VERSION=2.12.0
DART_VERSION=2.13.3
wget -nv https://storage.googleapis.com/dart-archive/channels/${DART_RELEASE_CHANNEL}/release/${DART_VERSION}/linux_packages/dart_${DART_VERSION}-1_amd64.deb
sudo apt -y install ./dart_${DART_VERSION}-1_amd64.deb
- name: Build and run functional tests
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Gluecodium project Release Notes

## Unreleased
### Features:
* Added support for type aliases (typedefs) in Dart
### Breaking changes:
* Generated Dart code now requires minimum Dart version 2.13.0.

## 10.2.3
Release date: 2021-11-10
### 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 @@ -67,6 +67,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 = [
BlobsTests.main,
Expand Down Expand Up @@ -113,7 +114,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: '>=2.13.0 <3.0.0'
dependencies:
test:
functional:
Expand Down
53 changes: 53 additions & 0 deletions functional-tests/functional/dart/test/TypeAliases_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// -------------------------------------------------------------------------------------------------
// 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(PointTypedef(1.0, 3.0));

expect(result is Point, isTrue);
expect(result.x, 1.0);
expect(result.y, 3.0);
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ internal class DartGenerator : Generator {
.sortedBy { ffiNameResolver.resolveName(it) }

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

val packagePath = rootElement.path.head.joinToString(separator = "/")
val fileName = dartNameResolver.resolveFileName(rootElement)
val filePath = "$packagePath/$fileName"
val relativePath = "$SRC_DIR_SUFFIX/$filePath.dart"

val allTypes = LimeTypeHelper.getAllTypes(rootElement).filterNot { it is LimeTypeAlias }
val allTypes = LimeTypeHelper.getAllTypes(rootElement)
val nonExternalTypes = allTypes.filter { it.external?.dart == null }
val freeConstants = (rootElement as? LimeTypesCollection)?.constants ?: emptyList()
val allSymbols =
Expand Down Expand Up @@ -512,7 +512,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 @@ -54,12 +54,12 @@ internal class DartImportResolver(
}

private fun resolveTypeImports(limeType: LimeType): List<DartImport> =
when (val actualType = limeType.actualType) {
is LimeBasicType -> resolveBasicTypeImports(actualType)
is LimeGenericType -> resolveGenericTypeImports(actualType)
when (limeType) {
is LimeBasicType -> resolveBasicTypeImports(limeType)
is LimeGenericType -> resolveGenericTypeImports(limeType)
else -> listOfNotNull(
createImport(actualType),
resolveExternalImport(actualType, IMPORT_PATH_NAME, useAlias = true)
createImport(limeType),
resolveExternalImport(limeType, IMPORT_PATH_NAME, useAlias = true)
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@ import com.here.gluecodium.model.lime.LimeClass
import com.here.gluecodium.model.lime.LimeContainerWithInheritance

internal class DartImportsCollector(importsResolver: ImportsResolver<DartImport>) :
GenericImportsCollector<DartImport>(importsResolver, collectTypeRefImports = true, parentTypeFilter = { true }) {
GenericImportsCollector<DartImport>(
importsResolver,
collectTypeRefImports = 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 @@ -44,7 +44,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.LimeTypeRef
import com.here.gluecodium.model.lime.LimeTypesCollection
import com.here.gluecodium.model.lime.LimeValue
Expand Down Expand Up @@ -80,7 +79,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 @@ -221,11 +219,11 @@ internal class DartNameResolver(

private fun resolveTypeRefName(limeTypeRef: LimeTypeRef, ignoreDuplicates: 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) "?" else ""
Expand Down Expand Up @@ -258,7 +256,7 @@ internal class DartNameResolver(
private fun buildDuplicateNames() =
limeReferenceMap.values
.filterIsInstance<LimeType>()
.filterNot { it is LimeTypesCollection || it is LimeTypeAlias || it is LimeGenericType || it is LimeBasicType }
.filterNot { it is LimeTypesCollection || 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 @@ -48,6 +48,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 @@ -64,6 +64,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: '>=2.13.0 <3.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 visibility}}{{resolveName}} = {{resolveName typeRef}};
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
! License-Filename: LICENSE
!
!}}
{{#typeAliases}}
{{>dart/DartTypeAlias}}
{{/typeAliases}}
{{#enumerations}}
{{>dart/DartEnumeration}}
{{/enumerations}}
Expand Down
Loading

0 comments on commit e37a9d5

Please sign in to comment.