Skip to content

Commit

Permalink
add support for global functions and variables
Browse files Browse the repository at this point in the history
  • Loading branch information
Mohammad3id committed Sep 27, 2024
1 parent 16918ae commit b29359c
Show file tree
Hide file tree
Showing 23 changed files with 541 additions and 213 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright (c) 2024, 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.

/// An interface to describe a Swift entity's compound membership
abstract interface class CompoundMemeber {
abstract final bool isStatic;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright (c) 2024, 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 '../shared/referred_type.dart';
import 'declaration.dart';
import 'executable.dart';
import 'parameterizable.dart';
import 'type_parameterizable.dart';

/// Describes a function-like entity.
abstract interface class FunctionDeclaration
implements Declaration, Parameterizable, Executable, TypeParameterizable {
abstract final ReferredType? returnType;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright (c) 2024, 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 '../shared/referred_type.dart';
import 'declaration.dart';

/// Describes a variable-like entity.
abstract interface class VariableDeclaration implements Declaration {
abstract final bool isConstant;
abstract final ReferredType type;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,14 @@
// 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 '../../../_core/interfaces/declaration.dart';
import '../../../_core/interfaces/executable.dart';
import '../../../_core/interfaces/function_declaration.dart';
import '../../../_core/interfaces/objc_annotatable.dart';
import '../../../_core/interfaces/parameterizable.dart';
import '../../../_core/interfaces/type_parameterizable.dart';
import '../../../_core/shared/parameter.dart';
import '../../../_core/shared/referred_type.dart';

/// Describes a method declaration for a Swift compound entity
/// (e.g, class, structs)
class MethodDeclaration
implements
Declaration,
TypeParameterizable,
Executable,
Parameterizable,
ObjCAnnotatable {
class MethodDeclaration implements FunctionDeclaration, ObjCAnnotatable {
@override
String id;

Expand All @@ -37,6 +28,7 @@ class MethodDeclaration
@override
List<String> statements;

@override
ReferredType? returnType;

bool isStatic;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
// 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 '../../../_core/interfaces/declaration.dart';
import '../../../_core/interfaces/executable.dart';
import '../../../_core/interfaces/objc_annotatable.dart';
import '../../../_core/interfaces/variable_declaration.dart';
import '../../../_core/shared/referred_type.dart';

/// Describes a property declaration for a Swift compound entity
/// (e.g, class, structs)
class PropertyDeclaration implements Declaration, ObjCAnnotatable {
class PropertyDeclaration implements VariableDeclaration, ObjCAnnotatable {
@override
String id;

Expand All @@ -19,25 +19,30 @@ class PropertyDeclaration implements Declaration, ObjCAnnotatable {
@override
bool hasObjCAnnotation;

@override
ReferredType type;

@override
bool isConstant;

bool hasSetter;

PropertyStatements? getter;
PropertyStatements? setter;

ReferredType type;

bool isStatic;

PropertyDeclaration({
required this.id,
required this.name,
required this.type,
this.hasSetter = false,
this.isConstant = false,
this.hasObjCAnnotation = false,
this.getter,
this.setter,
this.isStatic = false,
});
}) : assert(!isConstant || !hasSetter);
}

class PropertyStatements implements Executable {
Expand Down
29 changes: 17 additions & 12 deletions pkgs/swift2objc/lib/src/ast/declarations/globals/globals.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,25 @@
// 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 '../../_core/interfaces/declaration.dart';
import '../../_core/interfaces/parameterizable.dart';
import '../../_core/interfaces/type_parameterizable.dart';
import '../../_core/interfaces/function_declaration.dart';
import '../../_core/interfaces/variable_declaration.dart';
import '../../_core/shared/parameter.dart';
import '../../_core/shared/referred_type.dart';

/// A container for globally defined values (i.e variables & constants)
/// and functions.
class Globals {
List<GlobalFunctionDeclaration> functions;
List<GlobalValueDeclaration> values;
List<GlobalVariableDeclaration> variables;

Globals({
required this.functions,
required this.values,
required this.variables,
});
}

/// Describes a globally defined function.
class GlobalFunctionDeclaration
implements Declaration, Parameterizable, TypeParameterizable {
class GlobalFunctionDeclaration implements FunctionDeclaration {
@override
String id;

Expand All @@ -35,30 +33,37 @@ class GlobalFunctionDeclaration
@override
List<GenericType> typeParams;

ReferredType returnType;
@override
ReferredType? returnType;

@override
List<String> statements;

GlobalFunctionDeclaration({
required this.id,
required this.name,
required this.params,
required this.typeParams,
required this.returnType,
this.typeParams = const [],
this.statements = const [],
});
}

/// Describes a globally defined values (i.e variable/constant).
class GlobalValueDeclaration implements Declaration {
class GlobalVariableDeclaration implements VariableDeclaration {
@override
String id;

@override
String name;

DeclaredType type;
@override
ReferredType type;

@override
bool isConstant;

GlobalValueDeclaration({
GlobalVariableDeclaration({
required this.id,
required this.name,
required this.type,
Expand Down
4 changes: 2 additions & 2 deletions pkgs/swift2objc/lib/src/parser/_core/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ extension TopLevelOnly<T extends Declaration> on List<T> {
(declaration) =>
declaration is CompoundDeclaration ||
declaration is EnumDeclaration ||
declaration is GlobalValueDeclaration ||
declaration is GlobalVariableDeclaration ||
declaration is GlobalFunctionDeclaration,
).toList();
}
Expand All @@ -55,7 +55,7 @@ String parseSymbolName(Json symbolJson) {
.get();
}

bool symbolHasObjcAnnotation(Json symbolJson) {
bool parseSymbolHasObjcAnnotation(Json symbolJson) {
return symbolJson['declarationFragments'].any(
(json) =>
json['kind'].exists &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ InitializerDeclaration parseInitializerDeclaration(
return InitializerDeclaration(
id: parseSymbolId(initializerSymbolJson),
params: parseInitializerParams(initializerSymbolJson, symbolgraph),
hasObjCAnnotation: symbolHasObjcAnnotation(initializerSymbolJson),
hasObjCAnnotation: parseSymbolHasObjcAnnotation(initializerSymbolJson),
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import '../../../ast/_core/interfaces/declaration.dart';
import '../../../ast/_core/shared/referred_type.dart';
import '../../../ast/declarations/compounds/members/property_declaration.dart';
import '../../../ast/declarations/globals/globals.dart';
import '../../_core/json.dart';
import '../../_core/parsed_symbolgraph.dart';
import '../../_core/utils.dart';
Expand All @@ -11,17 +12,32 @@ PropertyDeclaration parsePropertyDeclaration(
ParsedSymbolgraph symbolgraph, {
bool isStatic = false,
}) {
final isConstant = _parseVariableIsConstant(propertySymbolJson);
return PropertyDeclaration(
id: parseSymbolId(propertySymbolJson),
name: parseSymbolName(propertySymbolJson),
type: _parsePropertyType(propertySymbolJson, symbolgraph),
hasObjCAnnotation: symbolHasObjcAnnotation(propertySymbolJson),
hasSetter: _propertyHasSetter(propertySymbolJson),
type: _parseVariableType(propertySymbolJson, symbolgraph),
hasObjCAnnotation: parseSymbolHasObjcAnnotation(propertySymbolJson),
isConstant: isConstant,
hasSetter: isConstant ? false : _parsePropertyHasSetter(propertySymbolJson),
isStatic: isStatic,
);
}

ReferredType _parsePropertyType(
GlobalVariableDeclaration parseGlobalVariableDeclaration(
Json variableSymbolJson,
ParsedSymbolgraph symbolgraph, {
bool isStatic = false,
}) {
return GlobalVariableDeclaration(
id: parseSymbolId(variableSymbolJson),
name: parseSymbolName(variableSymbolJson),
type: _parseVariableType(variableSymbolJson, symbolgraph),
isConstant: _parseVariableIsConstant(variableSymbolJson),
);
}

ReferredType _parseVariableType(
Json propertySymbolJson,
ParsedSymbolgraph symbolgraph,
) {
Expand All @@ -47,8 +63,8 @@ ReferredType _parsePropertyType(
return typeDeclaration.asDeclaredType;
}

bool _propertyHasSetter(Json propertySymbolJson) {
final fragmentsJson = propertySymbolJson['declarationFragments'];
bool _parseVariableIsConstant(Json variableSymbolJson) {
final fragmentsJson = variableSymbolJson['declarationFragments'];

final declarationKeywordJson = fragmentsJson.firstWhere(
(json) {
Expand All @@ -67,25 +83,38 @@ bool _propertyHasSetter(Json propertySymbolJson) {

final declarationKeyword = declarationKeywordJson['spelling'].get<String>();

if (declarationKeyword == 'var') {
final hasExplicitSetter = fragmentsJson.any(
(json) => json['spelling'].get<String>() == 'set',
);
return declarationKeyword == 'let';
}

final hasExplicitGetter = fragmentsJson.any(
(json) => json['spelling'].get<String>() == 'get',
);
bool _parsePropertyHasSetter(Json propertySymbolJson) {
final fragmentsJson = propertySymbolJson['declarationFragments'];

if (hasExplicitGetter) {
if (hasExplicitSetter) {
return true;
} else {
return false;
}
}
final hasExplicitSetter = fragmentsJson.any(
(json) => json['spelling'].get<String>() == 'set',
);

return true;
}
final hasExplicitGetter = fragmentsJson.any(
(json) => json['spelling'].get<String>() == 'get',
);

return false;
if (hasExplicitGetter) {
if (hasExplicitSetter) {
// has explicit getter and has explicit setter
return true;
} else {
// has explicit getter and no explicit setter
return false;
}
} else {
if (hasExplicitSetter) {
// has no explicit getter and but has explicit setter
throw Exception(
'Invalid property at ${propertySymbolJson.path}. '
'Properties can not have a setter without a getter',
);
} else {
// has no explicit getter and no explicit setter
return true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,24 @@ import '../../../ast/_core/interfaces/declaration.dart';
import '../../../ast/_core/shared/parameter.dart';
import '../../../ast/_core/shared/referred_type.dart';
import '../../../ast/declarations/compounds/members/method_declaration.dart';
import '../../../ast/declarations/globals/globals.dart';
import '../../_core/json.dart';
import '../../_core/parsed_symbolgraph.dart';
import '../../_core/utils.dart';
import '../parse_declarations.dart';

GlobalFunctionDeclaration parseGlobalFunctionDeclaration(
Json globalFunctionSymbolJson,
ParsedSymbolgraph symbolgraph,
) {
return GlobalFunctionDeclaration(
id: parseSymbolId(globalFunctionSymbolJson),
name: parseSymbolName(globalFunctionSymbolJson),
returnType: _parseFunctionReturnType(globalFunctionSymbolJson, symbolgraph),
params: _parseFunctionParams(globalFunctionSymbolJson, symbolgraph),
);
}

MethodDeclaration parseMethodDeclaration(
Json methodSymbolJson,
ParsedSymbolgraph symbolgraph, {
Expand All @@ -19,14 +32,14 @@ MethodDeclaration parseMethodDeclaration(
return MethodDeclaration(
id: parseSymbolId(methodSymbolJson),
name: parseSymbolName(methodSymbolJson),
returnType: _parseMethodReturnType(methodSymbolJson, symbolgraph),
params: _parseMethodParams(methodSymbolJson, symbolgraph),
hasObjCAnnotation: symbolHasObjcAnnotation(methodSymbolJson),
returnType: _parseFunctionReturnType(methodSymbolJson, symbolgraph),
params: _parseFunctionParams(methodSymbolJson, symbolgraph),
hasObjCAnnotation: parseSymbolHasObjcAnnotation(methodSymbolJson),
isStatic: isStatic,
);
}

ReferredType? _parseMethodReturnType(
ReferredType? _parseFunctionReturnType(
Json methodSymbolJson,
ParsedSymbolgraph symbolgraph,
) {
Expand Down Expand Up @@ -56,7 +69,7 @@ ReferredType? _parseMethodReturnType(
return returnTypeDeclaration.asDeclaredType;
}

List<Parameter> _parseMethodParams(
List<Parameter> _parseFunctionParams(
Json methodSymbolJson,
ParsedSymbolgraph symbolgraph,
) {
Expand Down
Loading

0 comments on commit b29359c

Please sign in to comment.