Files
sdk/pkg/vm_service/tool/java/src_gen_java.dart
T
Ben Konyi 6ae9f31081 Revert "Reland "[ VM / Service ] Add setIsolatePauseMode RPC""
This reverts commit 5de4830a4e.

Reason for revert: Unable to roll into google3

Original change's description:
> Reland "[ VM / Service ] Add setIsolatePauseMode RPC"
>
> This reverts commit d21897b88d.
>
> 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 commit cad8a34d83.
> >
> > 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>
2021-11-13 00:01:53 +00:00

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();
}
}