[jnigen] Reduce concatenation in binding generator code (https://github.com/dart-lang/jnigen/issues/102)

diff --git a/pkgs/jnigen/lib/src/bindings/c_bindings.dart b/pkgs/jnigen/lib/src/bindings/c_bindings.dart
index 3dda13a..bc3d61c 100644
--- a/pkgs/jnigen/lib/src/bindings/c_bindings.dart
+++ b/pkgs/jnigen/lib/src/bindings/c_bindings.dart
@@ -40,8 +40,8 @@
 
     // global variable in C that holds the reference to class
     final classVar = '${classVarPrefix}_$classNameInC';
-    s.write('// ${c.binaryName}\n');
-    s.write('jclass $classVar = NULL;\n\n');
+    s.write('// ${c.binaryName}\n'
+        'jclass $classVar = NULL;\n\n');
 
     for (var m in c.methods) {
       if (!m.isIncluded) {
@@ -72,50 +72,52 @@
     final s = StringBuffer();
     final name = m.finalName;
     final functionName = getMemberNameInC(c, name);
+    final classRef = '${classVarPrefix}_$classNameInC';
     final methodID = '${methodVarPrefix}_$functionName';
-    s.write('jmethodID $methodID = NULL;\n');
-
     final cMethodName = getMemberNameInC(c, name);
-    final cParams = _formalArgs(m);
-    s.write('FFI_PLUGIN_EXPORT\n');
-    s.write('$jniResultType $cMethodName($cParams) {\n');
-
-    final classVar = '${classVarPrefix}_$classNameInC';
+    final cMethodParams = _formalArgs(m);
     final jniSignature = getJniSignatureForMethod(m);
+    final ifStaticMethodID = isStatic ? 'static_' : '';
 
-    s.write(_loadEnvCall);
-    s.write(_loadClassCall(classVar, getInternalName(c.binaryName)));
-
-    final ifStatic = isStatic ? 'static_' : '';
-    s.write('${indent}load_${ifStatic}method($classVar, '
-        '&$methodID, "${m.name}", "$jniSignature");\n');
-    s.write('${indent}if ($methodID == NULL) return $ifError;\n');
-
-    var returnTypeName = m.returnType.name;
+    var javaReturnType = m.returnType.name;
     if (isACtor) {
-      returnTypeName = c.binaryName;
-    }
-
-    s.write(indent);
-    if (returnTypeName != 'void') {
-      s.write('${getCType(returnTypeName)} _result = ');
+      javaReturnType = c.binaryName;
     }
     final callType = _typeNameAtCallSite(m.returnType);
-    final callArgs = _callArgs(m, classVar, methodID);
-    if (isACtor) {
-      s.write('(*jniEnv)->NewObject($callArgs);\n');
-    } else {
-      final ifStatic = isStatic ? 'Static' : '';
-      s.write('(*jniEnv)->Call$ifStatic${callType}Method($callArgs);\n');
+    final callArgs = _callArgs(m, classRef, methodID);
+
+    var ifAssignResult = '';
+    if (javaReturnType != 'void') {
+      ifAssignResult = '${getCType(javaReturnType)} _result = ';
     }
-    s.write(_result(m));
-    s.write('}\n');
+
+    final ifStaticCall = isStatic ? 'Static' : '';
+    final envMethod =
+        isACtor ? 'NewObject' : 'Call$ifStaticCall${callType}Method';
+    final returnResultIfAny = _result(m);
+    s.write('''
+jmethodID $methodID = NULL;
+FFI_PLUGIN_EXPORT
+$jniResultType $cMethodName($cMethodParams) {
+    $_loadEnvCall
+    ${_loadClassCall(classRef, getInternalName(c.binaryName))}
+    load_${ifStaticMethodID}method($classRef,
+      &$methodID, "${m.name}", "$jniSignature");
+    if ($methodID == NULL) return $ifError;
+    $ifAssignResult(*jniEnv)->$envMethod($callArgs);
+    $returnResultIfAny
+}\n''');
     return s.toString();
   }
 
   String _field(ClassDecl c, Field f) {
     final cClassName = getUniqueClassName(c);
     final isStatic = isStaticField(f);
+
+    final fieldName = f.finalName;
+    final fieldNameInC = getMemberNameInC(c, fieldName);
+    final fieldVar = "${fieldVarPrefix}_$fieldNameInC";
+
     // If the field is final and default is assigned, then no need to wrap
     // this field. It should then be a constant in dart code.
     if (isStatic && isFinalField(f) && f.defaultValue != null) {
@@ -124,51 +126,49 @@
 
     final s = StringBuffer();
 
-    final fieldName = f.finalName;
-    final fieldNameInC = getMemberNameInC(c, fieldName);
-    final fieldVar = "${fieldVarPrefix}_$fieldNameInC";
     s.write('jfieldID $fieldVar = NULL;\n');
-    final classVar = '${classVarPrefix}_$cClassName';
 
+    final classVar = '${classVarPrefix}_$cClassName';
     void writeAccessor({bool isSetter = false}) {
-      final prefix = isSetter ? 'set' : 'get';
-      s.write('FFI_PLUGIN_EXPORT\n');
       const cReturnType = jniResultType;
-      s.write('$cReturnType ${prefix}_$fieldNameInC(');
+      final cMethodPrefix = isSetter ? 'set' : 'get';
       final formalArgs = <String>[
         if (!isStatic) 'jobject self_',
         if (isSetter) '${getCType(f.type.name)} value',
-      ];
-      s.write(formalArgs.join(', '));
-      s.write(') {\n');
-      s.write(_loadEnvCall);
-      s.write(_loadClassCall(classVar, getInternalName(c.binaryName)));
-
-      var ifStatic = isStatic ? 'static_' : '';
-      s.write(
-          '${indent}load_${ifStatic}field($classVar, &$fieldVar, "$fieldName",'
-          '"${_fieldSignature(f)}");\n');
-
-      ifStatic = isStatic ? 'Static' : '';
-      final self = isStatic ? classVar : 'self_';
+      ].join(', ');
+      final ifStaticField = isStatic ? 'static_' : '';
+      final ifStaticCall = isStatic ? 'Static' : '';
       final callType = _typeNameAtCallSite(f.type);
+      final objectArgument = isStatic ? classVar : 'self_';
+
+      String accessorStatements;
       if (isSetter) {
-        s.write('$indent(*jniEnv)->Set$ifStatic${callType}Field(jniEnv, '
-            '$self, $fieldVar, value);\n');
-        s.write('${indent}return $ifError;\n');
+        accessorStatements =
+            '$indent(*jniEnv)->Set$ifStaticCall${callType}Field(jniEnv, '
+            '$objectArgument, $fieldVar, value);\n'
+            '${indent}return $ifError;';
       } else {
-        var getterExpr = '(*jniEnv)->Get$ifStatic${callType}Field(jniEnv, '
-            '$self, $fieldVar)';
+        var getterExpr = '(*jniEnv)->Get$ifStaticCall${callType}Field(jniEnv, '
+            '$objectArgument, $fieldVar)';
         if (!isPrimitive(f.type)) {
           getterExpr = 'to_global_ref($getterExpr)';
         }
         final cResultType = getCType(f.type.name);
-        s.write('$indent$cResultType _result = $getterExpr;\n');
         final unionField = getJValueField(f.type);
-        s.write('${indent}return (JniResult){.result = '
-            '{.$unionField = _result}, .exception = check_exception()};\n');
+        accessorStatements = '$indent$cResultType _result = $getterExpr;\n'
+            '${indent}return (JniResult){.result = '
+            '{.$unionField = _result}, .exception = check_exception()};';
       }
-      s.write('}\n\n');
+
+      s.write('''
+FFI_PLUGIN_EXPORT
+$cReturnType ${cMethodPrefix}_$fieldNameInC($formalArgs) {
+    $_loadEnvCall
+    ${_loadClassCall(classVar, getInternalName(c.binaryName))}
+    load_${ifStaticField}field($classVar, &$fieldVar, "$fieldName",
+      "${_fieldSignature(f)}");
+$accessorStatements
+}\n\n''');
     }
 
     writeAccessor(isSetter: false);
@@ -179,12 +179,11 @@
     return s.toString();
   }
 
-  final String _loadEnvCall = '${indent}load_env();\n';
+  final String _loadEnvCall = '${indent}load_env();';
 
   String _loadClassCall(String classVar, String internalName) {
-    return '${indent}load_class_gr(&$classVar, '
-        '"$internalName");\n'
-        '${indent}if ($classVar == NULL) return $ifError;\n';
+    return '${indent}load_class_gr(&$classVar, "$internalName");\n'
+        '${indent}if ($classVar == NULL) return $ifError;';
   }
 
   String _formalArgs(Method m) {
@@ -253,7 +252,8 @@
       valuePart = '_result';
     }
     const exceptionPart = 'check_exception()';
-    return '${indent}return (JniResult){.result = {.$unionField = $valuePart}, .exception = $exceptionPart};\n';
+    return '${indent}return (JniResult){.result = {.$unionField = $valuePart}, '
+        '.exception = $exceptionPart};';
   }
 
   String _fieldSignature(Field f) {
diff --git a/pkgs/jnigen/lib/src/bindings/common.dart b/pkgs/jnigen/lib/src/bindings/common.dart
index 690dbc8..b7df2be 100644
--- a/pkgs/jnigen/lib/src/bindings/common.dart
+++ b/pkgs/jnigen/lib/src/bindings/common.dart
@@ -63,7 +63,7 @@
   /// Returns the formal parameters list of the generated function.
   ///
   /// This is the signature seen by the user.
-  String formalArgs(Method m, SymbolResolver resolver) {
+  String getFormalArgs(Method m, SymbolResolver resolver) {
     final List<String> args = [];
     for (var param in m.params) {
       args.add(
@@ -254,6 +254,7 @@
   return decl.uniqueName;
 }
 
+/// Returns the name of the class member as referred to by C bindings
 String getMemberNameInC(ClassDecl decl, String name) =>
     "${getUniqueClassName(decl)}__$name";
 
diff --git a/pkgs/jnigen/lib/src/bindings/dart_bindings.dart b/pkgs/jnigen/lib/src/bindings/dart_bindings.dart
index 5096b83..2ccd5a1 100644
--- a/pkgs/jnigen/lib/src/bindings/dart_bindings.dart
+++ b/pkgs/jnigen/lib/src/bindings/dart_bindings.dart
@@ -58,11 +58,8 @@
           jniObjectType;
     }
 
-    s.write('class $name extends $superName {\n');
-    s.write('$indent$name.fromRef($voidPointer ref) : '
-        'super.fromRef(ref);\n');
-
-    s.writeln();
+    s.write('class $name extends $superName {\n'
+        '$indent$name.fromRef($voidPointer ref) : super.fromRef(ref);\n\n');
 
     for (var field in decl.fields) {
       if (!field.isIncluded) {
@@ -100,12 +97,15 @@
     final sym = '_$name';
     final ffiSig = dartSigForMethod(m, isFfiSig: true);
     final dartSig = dartSigForMethod(m, isFfiSig: false);
+    final returnType = getDartOuterType(m.returnType, resolver);
+    final ifStaticMethod = isStaticMethod(m) ? 'static' : '';
+
+    // Load corresponding C method.
     s.write('${indent}static final $sym = $lookup'
         '<${ffi}NativeFunction<$ffiSig>>("$cName")\n'
         '.asFunction<$dartSig>();\n');
     // Different logic for constructor and method;
     // For constructor, we want return type to be new object.
-    final returnType = getDartOuterType(m.returnType, resolver);
     s.write('$indent/// from: ${getOriginalMethodHeader(m)}\n');
     if (!isPrimitive(m.returnType)) {
       s.write(BindingsGenerator.deleteInstruction);
@@ -113,15 +113,11 @@
     s.write(breakDocComment(m.javadoc));
     s.write(indent);
 
-    if (isStaticMethod(m)) {
-      s.write('static ');
-    }
-
     if (isCtor(m)) {
-      final wrapperExpr = '$sym(${actualArgs(m)})';
       final className = c.finalName;
       final ctorFnName = name == 'ctor' ? className : '$className.$name';
-      s.write('$ctorFnName(${formalArgs(m, resolver)}) : '
+      final wrapperExpr = '$sym(${actualArgs(m)})';
+      s.write('$ctorFnName(${getFormalArgs(m, resolver)}) : '
           'super.fromRef($wrapperExpr.object);\n');
       return s.toString();
     }
@@ -129,8 +125,9 @@
     final resultGetter = getJValueAccessor(m.returnType);
     var wrapperExpr = '$sym(${actualArgs(m)}).$resultGetter';
     wrapperExpr = toDartResult(wrapperExpr, m.returnType, returnType);
-    s.write('$returnType $name(${formalArgs(m, resolver)}) => ');
-    s.write('$wrapperExpr;\n');
+    final params = getFormalArgs(m, resolver);
+    s.write('$indent$ifStaticMethod $returnType $name($params) '
+        '=> $wrapperExpr;\n');
     return s.toString();
   }
 
@@ -148,10 +145,11 @@
 
     if (isStaticField(f) && isFinalField(f) && f.defaultValue != null) {
       writeDocs(writeDeleteInstruction: false);
-      s.write(
-          '${indent}static const $name = ${getDartLiteral(f.defaultValue)};\n');
+      s.write('${indent}static const $name = '
+          '${getDartLiteral(f.defaultValue)};\n');
       return s.toString();
     }
+
     final cName = getMemberNameInC(c, name);
 
     void writeAccessor({bool isSetter = false}) {
@@ -162,31 +160,30 @@
       s.write('${indent}static final $sym = $lookup'
           '<${ffi}NativeFunction<$ffiSig>>("${symPrefix}_$cName")\n'
           '.asFunction<$dartSig>();\n');
-      // write original type
       writeDocs();
-      s.write(indent);
-      if (isStaticField(f)) s.write('static ');
+      final ifStatic = isStaticField(f) ? 'static' : '';
       if (isSetter) {
-        s.write(
-            'set $name(${getDartOuterType(f.type, resolver)} value) => $sym(');
-        if (!isStaticField(f)) {
-          s.write('$selfPointer, ');
-        }
-        s.write(toNativeArg('value', f.type));
-        s.write(');\n');
+        final args = [
+          if (!isStaticField(f)) selfPointer,
+          toNativeArg('value', f.type),
+        ].join(', ');
+        final valueOuterType = getDartOuterType(f.type, resolver);
+        s.write('$indent$ifStatic set $name($valueOuterType value) => '
+            '$sym($args);\n');
       } else {
         // getter
         final self = isStaticField(f) ? '' : selfPointer;
-        final outer = getDartOuterType(f.type, resolver);
+        final outerType = getDartOuterType(f.type, resolver);
         final resultGetter = getJValueAccessor(f.type);
         final callExpr = '$sym($self).$resultGetter';
-        final resultExpr = toDartResult(callExpr, f.type, outer);
-        s.write('$outer get $name => $resultExpr;\n');
+        final resultExpr = toDartResult(callExpr, f.type, outerType);
+        s.write('$indent$ifStatic $outerType get $name => $resultExpr;\n');
       }
     }
 
     writeAccessor(isSetter: false);
     if (!isFinalField(f)) writeAccessor(isSetter: true);
+    s.writeln();
     return s.toString();
   }