Skip to content

Commit

Permalink
Handle reserved Kotlin keywords (flutter#86518)
Browse files Browse the repository at this point in the history
  • Loading branch information
asashour authored Aug 2, 2021
1 parent 2971bf6 commit 92e0245
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 0 deletions.
19 changes: 19 additions & 0 deletions packages/flutter_tools/lib/src/template.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ import 'base/template.dart';
import 'cache.dart';
import 'dart/package_map.dart';

/// The Kotlin keywords which are not Java keywords.
/// They are escaped in Kotlin files.
///
/// https://kotlinlang.org/docs/keyword-reference.html
const List<String> kReservedKotlinKeywords = <String>['when', 'in'];

/// Expands templates in a directory to a destination. All files that must
/// undergo template expansion should end with the '.tmpl' extension. All files
/// that should be replaced with the corresponding image from
Expand Down Expand Up @@ -322,6 +328,11 @@ class Template {

if (sourceFile.path.endsWith(templateExtension)) {
final String templateContents = sourceFile.readAsStringSync();
final String? androidIdentifier = context['androidIdentifier'] as String?;
if (finalDestinationFile.path.endsWith('.kt') && androidIdentifier != null) {
context['androidIdentifier'] = _escapeKotlinKeywords(androidIdentifier);
}

final String renderedContents = _templateRenderer.renderString(templateContents, context);

finalDestinationFile.writeAsStringSync(renderedContents);
Expand Down Expand Up @@ -360,3 +371,11 @@ Future<Directory> _templateImageDirectory(String name, FileSystem fileSystem, Lo
.childDirectory('templates')
.childDirectory(name);
}

String _escapeKotlinKeywords(String androidIdentifier) {
final List<String> segments = androidIdentifier.split('.');
final List<String> correctedSegments = segments.map(
(String segment) => kReservedKotlinKeywords.contains(segment) ? '`$segment`' : segment
).toList();
return correctedSegments.join('.');
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/isolated/mustache_template.dart';
import 'package:flutter_tools/src/template.dart';

import '../../src/common.dart';

void main() {

testWithoutContext('kotlin reserved keywords', () {
final FileSystem fileSystem = MemoryFileSystem.test();
final BufferLogger logger = BufferLogger.test();
final Directory rootDir = fileSystem.currentDirectory;
final Directory templateSource = rootDir.childDirectory('src');
final Directory imageSourceDir = templateSource;
final Directory destination = rootDir.childDirectory('dest');

const String outputClass = 'SomeClass.kt';

final File sourceFile = templateSource.childFile('$outputClass.tmpl');

templateSource.createSync();
sourceFile.writeAsStringSync('package {{androidIdentifier}};');

final Template template = Template(
templateSource,
imageSourceDir,
fileSystem: fileSystem,
logger: logger,
templateRenderer: const MustacheTemplateRenderer(),
templateManifest: null
);

final Map<String, Object> context = <String, Object>{
'androidIdentifier': 'in.when.there'
};
template.render(destination, context);

final File destinationFile = destination.childFile(outputClass);
expect(destinationFile.readAsStringSync(), equals('package `in`.`when`.there;'));
});

}

0 comments on commit 92e0245

Please sign in to comment.