• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

dart-lang / ffigen / 4784152981

24 Apr 2023 08:39AM UTC coverage: 92.363% (-7.0%) from 99.366%
4784152981

push

github

GitHub
Merge pull request #560 from dart-lang/stable-to-7-x

1780 of 1780 new or added lines in 41 files covered. (100.0%)

3229 of 3496 relevant lines covered (92.36%)

25.17 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.67
/lib/src/header_parser/sub_parsers/functiondecl_parser.dart
1
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2
// for details. All rights reserved. Use of this source code is governed by a
3
// BSD-style license that can be found in the LICENSE file.
4

5
import 'package:ffigen/src/code_generator.dart';
6
import 'package:ffigen/src/header_parser/data.dart';
7
import 'package:logging/logging.dart';
8

9
import '../clang_bindings/clang_bindings.dart' as clang_types;
10
import '../includer.dart';
11
import '../utils.dart';
12

13
final _logger = Logger('ffigen.header_parser.functiondecl_parser');
66✔
14

15
/// Holds temporary information regarding [Func] while parsing.
16
class _ParserFunc {
17
  Func? func;
18
  bool incompleteStructParameter = false;
19
  bool unimplementedParameterType = false;
20
  _ParserFunc();
24✔
21
}
22

23
final _stack = Stack<_ParserFunc>();
72✔
24

25
/// Parses a function declaration.
26
Func? parseFunctionDeclaration(clang_types.CXCursor cursor) {
24✔
27
  _stack.push(_ParserFunc());
72✔
28

29
  final funcUsr = cursor.usr();
24✔
30
  final funcName = cursor.spelling();
24✔
31
  if (shouldIncludeFunc(funcUsr, funcName)) {
24✔
32
    _logger.fine('++++ Adding Function: ${cursor.completeStringRepr()}');
88✔
33

34
    final rt = _getFunctionReturnType(cursor);
22✔
35
    final parameters = _getParameters(cursor, funcName);
22✔
36

37
    if (clang.clang_Cursor_isFunctionInlined(cursor) != 0) {
66✔
38
      _logger.fine('---- Removed Function, reason: inline function: '
3✔
39
          '${cursor.completeStringRepr()}');
1✔
40
      _logger.warning(
2✔
41
          "Skipped Function '$funcName', inline functions are not supported.");
1✔
42
      // Returning null so that [addToBindings] function excludes this.
43
      return _stack.pop().func;
3✔
44
    }
45

46
    if (rt.isIncompleteCompound || _stack.top.incompleteStructParameter) {
88✔
47
      _logger.fine(
×
48
          '---- Removed Function, reason: Incomplete struct pass/return by '
49
          'value: ${cursor.completeStringRepr()}');
×
50
      _logger.warning(
×
51
          "Skipped Function '$funcName', Incomplete struct pass/return by "
52
          'value not supported.');
53
      // Returning null so that [addToBindings] function excludes this.
54
      return _stack.pop().func;
×
55
    }
56

57
    if (rt.baseType is UnimplementedType ||
44✔
58
        _stack.top.unimplementedParameterType) {
66✔
59
      _logger.fine('---- Removed Function, reason: unsupported return type or '
9✔
60
          'parameter type: ${cursor.completeStringRepr()}');
3✔
61
      _logger.warning(
9✔
62
          "Skipped Function '$funcName', function has unsupported return type "
63
          'or parameter type.');
64
      // Returning null so that [addToBindings] function excludes this.
65
      return _stack.pop().func;
9✔
66
    }
67

68
    _stack.top.func = Func(
88✔
69
      dartDoc: getCursorDocComment(
22✔
70
        cursor,
71
        nesting.length + commentPrefix.length,
66✔
72
      ),
73
      usr: funcUsr,
74
      name: config.functionDecl.renameUsingConfig(funcName),
66✔
75
      originalName: funcName,
76
      returnType: rt,
77
      parameters: parameters,
78
      exposeSymbolAddress:
79
          config.functionDecl.shouldIncludeSymbolAddress(funcName),
66✔
80
      exposeFunctionTypedefs:
81
          config.exposeFunctionTypedefs.shouldInclude(funcName),
66✔
82
      isLeaf: config.leafFunctions.shouldInclude(funcName),
66✔
83
      ffiNativeConfig: config.ffiNativeConfig,
44✔
84
    );
85
    bindingsIndex.addFuncToSeen(funcUsr, _stack.top.func!);
110✔
86
  } else if (bindingsIndex.isSeenFunc(funcUsr)) {
14✔
87
    _stack.top.func = bindingsIndex.getSeenFunc(funcUsr);
5✔
88
  }
89

90
  return _stack.pop().func;
72✔
91
}
92

93
Type _getFunctionReturnType(clang_types.CXCursor cursor) {
22✔
94
  return cursor.returnType().toCodeGenType();
44✔
95
}
96

97
List<Parameter> _getParameters(clang_types.CXCursor cursor, String funcName) {
22✔
98
  final parameters = <Parameter>[];
22✔
99

100
  final totalArgs = clang.clang_Cursor_getNumArguments(cursor);
44✔
101
  for (var i = 0; i < totalArgs; i++) {
41✔
102
    final paramCursor = clang.clang_Cursor_getArgument(cursor, i);
38✔
103

104
    _logger.finer('===== parameter: ${paramCursor.completeStringRepr()}');
76✔
105

106
    final pt = _getParameterType(paramCursor);
19✔
107
    if (pt.isIncompleteCompound) {
19✔
108
      _stack.top.incompleteStructParameter = true;
×
109
    } else if (pt.baseType is UnimplementedType) {
38✔
110
      _logger.finer('Unimplemented type: ${pt.baseType}');
12✔
111
      _stack.top.unimplementedParameterType = true;
9✔
112
    }
113

114
    final pn = paramCursor.spelling();
19✔
115

116
    /// If [pn] is null or empty, its set to `arg$i` by code_generator.
117
    parameters.add(
19✔
118
      Parameter(
19✔
119
        originalName: pn,
120
        name: config.functionDecl.renameMemberUsingConfig(funcName, pn),
57✔
121
        type: pt,
122
      ),
123
    );
124
  }
125

126
  return parameters;
127
}
128

129
Type _getParameterType(clang_types.CXCursor cursor) {
19✔
130
  return cursor.toCodeGenType();
19✔
131
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc