blob: 97b2604d2e9efb9622d3ae450afbacf53d68dadf [file]
// Copyright (c) 2023, 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.
import '../elements/elements.dart';
import 'visitor.dart';
/// JVM representation of type signatures.
///
/// https://docs.oracle.com/en/java/javase/18/docs/specs/jni/types.html#type-signatures
class Descriptor extends TypeVisitor<String> {
const Descriptor();
@override
String visitArrayType(ArrayType node) {
final inner = node.type.accept(this);
return '[$inner';
}
@override
String visitDeclaredType(DeclaredType node) {
final internalName = node.binaryName.replaceAll('.', '/');
return 'L$internalName;';
}
@override
String visitPrimitiveType(PrimitiveType node) {
return node.signature;
}
@override
String visitTypeVar(TypeVar node) {
// It should be possible to compute the erasure of a type
// in parser itself.
// TODO(#23): Use erasure of the type variable here.
// This is just a (wrong) placeholder
return super.visitTypeVar(node);
}
@override
String visitWildcard(Wildcard node) {
final extendsBound = node.extendsBound?.accept(this);
return extendsBound ?? 'Ljava/lang/Object;';
}
@override
String visitNonPrimitiveType(ReferredType node) {
return "Ljava/lang/Object;";
}
}
/// Generates JNI Method signatures.
///
/// https://docs.oracle.com/en/java/javase/18/docs/specs/jni/types.html#type-signatures
/// Also see: [Descriptor]
class MethodSignature extends Visitor<Method, String> {
const MethodSignature();
@override
String visit(Method node) {
final s = StringBuffer();
s.write('(');
s.write(node.params
.map((param) => param.type)
.accept(const Descriptor())
.join());
s.write(')');
final returnType = node.returnType.accept(const Descriptor());
s.write(returnType);
return s.toString();
}
}
class CFieldName extends Visitor<Field, String> {
const CFieldName();
@override
String visit(Field node) {
final className = node.classDecl.uniqueName;
final fieldName = node.finalName;
return '${className}__$fieldName';
}
}
class CMethodName extends Visitor<Method, String> {
const CMethodName();
@override
String visit(Method node) {
final className = node.classDecl.uniqueName;
final methodName = node.finalName;
return '${className}__$methodName';
}
}