6ae9f31081
This reverts commit5de4830a4e. Reason for revert: Unable to roll into google3 Original change's description: > Reland "[ VM / Service ] Add setIsolatePauseMode RPC" > > This reverts commitd21897b88d. > > Reason for revert: Reland before fixing failures in google3 (requires copybara update of package:vm_service which requires this change to have already been landed in the SDK). > > Original change's description: > > Revert "[ VM / Service ] Add setIsolatePauseMode RPC" > > > > This reverts commitcad8a34d83. > > > > Reason for revert: broke the g3 cbuild, see cbuild logs > > (Error: The method 'setIsolatePauseMode' isn't defined for the class 'VmServiceInterface') > > > > Original change's description: > > > [ VM / Service ] Add setIsolatePauseMode RPC > > > > > > Allows for service clients to set pause behaviors on a per-isolate > > > basis at runtime. setIsolatePauseMode is a more general version of > > > setExceptionPauseMode and setExceptionPauseMode has been marked as deprecated. > > > > > > TEST=pause_on_exceptions_*_test.dart,should_pause_on_exit_test.dart > > > > > > Change-Id: I09d80aa2123791dd74d02441c162c19cc0486955 > > > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/219580 > > > Commit-Queue: Ben Konyi <bkonyi@google.com> > > > Reviewed-by: Siva Annamalai <asiva@google.com> > > > > TBR=bkonyi@google.com,rmacnak@google.com,asiva@google.com > > > > Change-Id: Ic326c54e0fd682e382bd70e36d87467d4148c990 > > No-Presubmit: true > > No-Tree-Checks: true > > No-Try: true > > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/220067 > > Reviewed-by: Siva Annamalai <asiva@google.com> > > Commit-Queue: Siva Annamalai <asiva@google.com> > > # Not skipping CQ checks because this is a reland. > > Change-Id: I0e25654e1991b7246cd413454ef45594d36f4bde > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/220127 > Reviewed-by: Siva Annamalai <asiva@google.com> TBR=bkonyi@google.com,rmacnak@google.com,asiva@google.com Change-Id: I9f1a2e81c99bfb90ddf0b4298bcb6c60e7e69dd3 No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/220130 Reviewed-by: Ben Konyi <bkonyi@google.com> Commit-Queue: Ben Konyi <bkonyi@google.com>
308 lines
9.0 KiB
Dart
308 lines
9.0 KiB
Dart
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
/// A library to generate Java source code. See [JavaGenerator].
|
|
library src_gen_java;
|
|
|
|
import 'dart:io';
|
|
|
|
import 'package:path/path.dart';
|
|
|
|
import '../common/src_gen_common.dart';
|
|
|
|
/// The maximum length for javadoc comments.
|
|
int colBoundary = 100;
|
|
|
|
/// The header for every generated file.
|
|
String? fileHeader;
|
|
|
|
String classNameFor(String typeName) {
|
|
// Convert ElementList<Foo> param declarations to List<Foo> declarations.
|
|
if (typeName.startsWith('ElementList<')) {
|
|
return typeName.substring('Element'.length);
|
|
}
|
|
|
|
var index = typeName.lastIndexOf('.');
|
|
typeName = index > 0 ? typeName.substring(index + 1) : typeName;
|
|
if (typeName.startsWith('_')) typeName = typeName.substring(1);
|
|
return typeName;
|
|
}
|
|
|
|
String pkgNameFor(String typeName) {
|
|
var index = typeName.lastIndexOf('.');
|
|
return index > 0 ? typeName.substring(0, index) : '';
|
|
}
|
|
|
|
typedef WriteStatements = void Function(StatementWriter writer);
|
|
typedef WriteType = void Function(TypeWriter writer);
|
|
|
|
/// [JavaGenerator] generates java source files, one per Java type.
|
|
/// Typical usage:
|
|
///
|
|
/// var generator = new JavaGenerator('/path/to/java/src');
|
|
/// generator.writeType('some.package.Foo', (TypeWriter) writer) {
|
|
/// ...
|
|
/// });
|
|
/// ...
|
|
///
|
|
class JavaGenerator {
|
|
/// The java source directory into which files are generated.
|
|
final String srcDirPath;
|
|
|
|
Set<String> _generatedPaths = Set();
|
|
|
|
JavaGenerator(this.srcDirPath);
|
|
|
|
Iterable<String> get allWrittenFiles => _generatedPaths;
|
|
|
|
/// Generate a Java class/interface in the given package
|
|
void writeType(String typeName, WriteType write) {
|
|
var classWriter = TypeWriter(typeName);
|
|
write(classWriter);
|
|
var pkgDirPath = join(srcDirPath, joinAll(pkgNameFor(typeName).split('.')));
|
|
var pkgDir = Directory(pkgDirPath);
|
|
if (!pkgDir.existsSync()) pkgDir.createSync(recursive: true);
|
|
var classFilePath = join(pkgDirPath, '${classNameFor(typeName)}.java');
|
|
var classFile = File(classFilePath);
|
|
_generatedPaths.add(classFilePath);
|
|
classFile.writeAsStringSync(classWriter.toSource());
|
|
}
|
|
}
|
|
|
|
class JavaMethodArg {
|
|
final String? name;
|
|
final String? typeName;
|
|
|
|
JavaMethodArg(this.name, this.typeName);
|
|
}
|
|
|
|
class StatementWriter {
|
|
final TypeWriter typeWriter;
|
|
final StringBuffer _content = StringBuffer();
|
|
|
|
StatementWriter(this.typeWriter);
|
|
|
|
void addImport(String typeName) {
|
|
typeWriter.addImport(typeName);
|
|
}
|
|
|
|
void addLine(String line) {
|
|
_content.writeln(' $line');
|
|
}
|
|
|
|
String toSource() => _content.toString();
|
|
}
|
|
|
|
/// [TypeWriter] describes a Java type to be generated.
|
|
/// Typical usage:
|
|
///
|
|
/// writer.addImport('package.one.Bar');
|
|
/// writer.addImport('package.two.*');
|
|
/// writer.superclassName = 'package.three.Blat';
|
|
/// writer.addMethod('foo', [
|
|
/// new JavaMethodArg('arg1', 'LocalType'),
|
|
/// new JavaMethodArg('arg2', 'java.util.List'),
|
|
/// ], (StatementWriter writer) {
|
|
/// ...
|
|
/// });
|
|
///
|
|
/// The [toSource()] method generates the source,
|
|
/// but need not be called if used in conjunction with
|
|
/// [JavaGenerator].
|
|
class TypeWriter {
|
|
final String pkgName;
|
|
final String className;
|
|
bool isInterface = false;
|
|
bool isEnum = false;
|
|
String? javadoc;
|
|
String modifiers = 'public';
|
|
final Set<String> _imports = Set<String>();
|
|
String? superclassName;
|
|
List<String> interfaceNames = <String>[];
|
|
final StringBuffer _content = StringBuffer();
|
|
final List<String> _fields = <String>[];
|
|
final Map<String, String> _methods = Map<String, String>();
|
|
|
|
TypeWriter(String typeName)
|
|
: this.pkgName = pkgNameFor(typeName),
|
|
this.className = classNameFor(typeName);
|
|
|
|
String get kind {
|
|
if (isInterface) return 'interface';
|
|
if (isEnum) return 'enum';
|
|
return 'class';
|
|
}
|
|
|
|
void addConstructor(Iterable<JavaMethodArg> args, WriteStatements write,
|
|
{String? javadoc, String modifiers = 'public'}) {
|
|
_content.writeln();
|
|
if (javadoc != null && javadoc.isNotEmpty) {
|
|
_content.writeln(' /**');
|
|
wrap(javadoc.trim(), colBoundary - 6)
|
|
.split('\n')
|
|
.forEach((line) => _content.writeln(' * $line'));
|
|
_content.writeln(' */');
|
|
}
|
|
_content.write(' $modifiers $className(');
|
|
_content.write(
|
|
args.map((a) => '${classNameFor(a.typeName!)} ${a.name}').join(', '));
|
|
_content.write(')');
|
|
_content.writeln(' {');
|
|
StatementWriter writer = StatementWriter(this);
|
|
write(writer);
|
|
_content.write(writer.toSource());
|
|
_content.writeln(' }');
|
|
}
|
|
|
|
void addEnumValue(
|
|
String? name, {
|
|
String? javadoc,
|
|
bool isLast = false,
|
|
}) {
|
|
_content.writeln();
|
|
if (javadoc != null && javadoc.isNotEmpty) {
|
|
_content.writeln(' /**');
|
|
wrap(javadoc.trim(), colBoundary - 6)
|
|
.split('\n')
|
|
.forEach((line) => _content.writeln(' * $line'));
|
|
_content.writeln(' */');
|
|
}
|
|
_content.write(' $name');
|
|
if (!isLast) {
|
|
_content.writeln(',');
|
|
} else {
|
|
_content.writeln();
|
|
}
|
|
}
|
|
|
|
void addField(String name, String typeName,
|
|
{String modifiers = 'public', String? value, String? javadoc}) {
|
|
var fieldDecl = StringBuffer();
|
|
if (javadoc != null && javadoc.isNotEmpty) {
|
|
fieldDecl.writeln(' /**');
|
|
wrap(javadoc.trim(), colBoundary - 6)
|
|
.split('\n')
|
|
.forEach((line) => fieldDecl.writeln(' * $line'));
|
|
fieldDecl.writeln(' */');
|
|
}
|
|
fieldDecl.write(' ');
|
|
if (modifiers.isNotEmpty) {
|
|
fieldDecl.write('$modifiers ');
|
|
}
|
|
fieldDecl.write('$typeName $name');
|
|
if (value != null && value.isNotEmpty) {
|
|
fieldDecl.write(' = $value');
|
|
}
|
|
fieldDecl.writeln(';');
|
|
_fields.add(fieldDecl.toString());
|
|
}
|
|
|
|
void addImport(String? typeName) {
|
|
if (typeName == null || typeName.isEmpty) return;
|
|
var pkgName = pkgNameFor(typeName);
|
|
if (pkgName.isNotEmpty && pkgName != this.pkgName) {
|
|
_imports.add(typeName);
|
|
}
|
|
}
|
|
|
|
void addMethod(
|
|
String name,
|
|
Iterable<JavaMethodArg> args,
|
|
WriteStatements? write, {
|
|
String? javadoc,
|
|
String? modifiers = 'public',
|
|
String? returnType = 'void',
|
|
bool isOverride = false,
|
|
}) {
|
|
var methodDecl = StringBuffer();
|
|
if (javadoc != null && javadoc.isNotEmpty) {
|
|
methodDecl.writeln(' /**');
|
|
wrap(javadoc.trim(), colBoundary - 6)
|
|
.split('\n')
|
|
.forEach((line) => methodDecl.writeln(' * $line'.trimRight()));
|
|
methodDecl.writeln(' */');
|
|
}
|
|
if (isOverride) {
|
|
methodDecl.writeln(' @Override');
|
|
}
|
|
methodDecl.write(' ');
|
|
if (modifiers != null && modifiers.isNotEmpty) {
|
|
if (!isInterface || modifiers != 'public') {
|
|
methodDecl.write('$modifiers ');
|
|
}
|
|
}
|
|
methodDecl.write('$returnType $name(');
|
|
methodDecl.write(args
|
|
.map(
|
|
(JavaMethodArg arg) => '${classNameFor(arg.typeName!)} ${arg.name}')
|
|
.join(', '));
|
|
methodDecl.write(')');
|
|
if (write != null) {
|
|
methodDecl.writeln(' {');
|
|
StatementWriter writer = StatementWriter(this);
|
|
write(writer);
|
|
methodDecl.write(writer.toSource());
|
|
methodDecl.writeln(' }');
|
|
} else {
|
|
methodDecl.writeln(';');
|
|
}
|
|
String key = (modifiers != null && modifiers.contains('public'))
|
|
? '1 $name('
|
|
: '2 $name(';
|
|
key = args.fold(key, (String k, JavaMethodArg a) => '$k${a.typeName},');
|
|
_methods[key] = methodDecl.toString();
|
|
}
|
|
|
|
String toSource() {
|
|
var buffer = StringBuffer();
|
|
if (fileHeader != null) buffer.write(fileHeader);
|
|
buffer.writeln('package $pkgName;');
|
|
buffer.writeln();
|
|
buffer.writeln('// This is a generated file.');
|
|
buffer.writeln();
|
|
addImport(superclassName);
|
|
interfaceNames.forEach((t) => addImport(t));
|
|
if (_imports.isNotEmpty) {
|
|
var sorted = _imports.toList()..sort();
|
|
for (String typeName in sorted) {
|
|
buffer.writeln('import $typeName;');
|
|
}
|
|
buffer.writeln();
|
|
}
|
|
if (javadoc != null && javadoc!.isNotEmpty) {
|
|
buffer.writeln('/**');
|
|
wrap(javadoc!.trim(), colBoundary - 4)
|
|
.split('\n')
|
|
.forEach((line) => buffer.writeln(' * $line'));
|
|
buffer.writeln(' */');
|
|
}
|
|
|
|
buffer.writeln('@SuppressWarnings({"WeakerAccess", "unused"})');
|
|
|
|
buffer.write('$modifiers $kind $className');
|
|
if (superclassName != null) {
|
|
buffer.write(' extends ${classNameFor(superclassName!)}');
|
|
}
|
|
if (interfaceNames.isNotEmpty) {
|
|
var classNames = interfaceNames.map((t) => classNameFor(t));
|
|
buffer.write(
|
|
' ${isInterface ? 'extends' : 'implements'} ${classNames.join(', ')}');
|
|
}
|
|
buffer.writeln(' {');
|
|
buffer.write(_content.toString());
|
|
_fields.forEach((f) {
|
|
buffer.writeln();
|
|
buffer.write(f);
|
|
});
|
|
_methods.keys.toList()
|
|
..sort()
|
|
..forEach((String methodName) {
|
|
buffer.writeln();
|
|
buffer.write(_methods[methodName]);
|
|
});
|
|
buffer.writeln('}');
|
|
return buffer.toString();
|
|
}
|
|
}
|