Skip to content
This repository has been archived by the owner on Nov 29, 2020. It is now read-only.

Commit

Permalink
fixed canvas issues; workarounds for missing interfaces; manually set…
Browse files Browse the repository at this point in the history
… binding namespaces
  • Loading branch information
krdmllr committed Jan 2, 2019
1 parent ade29ab commit 5e48e24
Show file tree
Hide file tree
Showing 9 changed files with 180 additions and 103 deletions.
2 changes: 1 addition & 1 deletion AST/analyzer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ main() async {
var namespaceDartName =
Naming.namespaceFromIdentifier(element.library.identifier);
var code = Frame.printNamespace(element, namespaceDartName);

var file = new File(
"${outputPath.absolute.path}\\${namespaceParts.join("\\")}.cs");
if (!await file.exists()) await file.create(recursive: true);
Expand Down
27 changes: 16 additions & 11 deletions AST/naming.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ class Naming {
static List<String> namespacePartsFromIdentifier(String identifier) {
var namespacePath = identifier
.replaceAll(
"file:///" + Config.sourcePath.replaceAll("\\", "/") + "/",
"")
"file:///" + Config.sourcePath.replaceAll("\\", "/") + "/", "")
.replaceAll(".dart", "")
.replaceAll("package:flutter/src/", "");

Expand Down Expand Up @@ -47,7 +46,7 @@ class Naming {
static String interfaceTypeName(InterfaceType type) {
var name = type.name;
name = getFormattedName(name, NameStyle.UpperCamelCase);

var typeArguments = new List<String>();
for (var argument in type.typeArguments) {
typeArguments.add(Types.getDartTypeName(argument));
Expand All @@ -62,7 +61,7 @@ class Naming {
TypeParameterizedElement element, bool isInterface) {
var name = element.name;
name = getFormattedName(name, NameStyle.UpperCamelCase);

if (isInterface) name = "I" + name;
var typeArguments = new List<String>();
for (var argument in element.typeParameters) {
Expand All @@ -88,7 +87,7 @@ class Naming {
}
return name;
}

static String getReturnType(FunctionTypedElement element) {
var returnType = element.returnType;
var returnName = returnType.displayName;
Expand All @@ -100,10 +99,8 @@ class Naming {
var t = test.returnType as TypeName;
returnName = t.name.name;
}
}
else if (test is FunctionDeclaration)
{
if (test.returnType is TypeName) {
} else if (test is FunctionDeclaration) {
if (test.returnType is TypeName) {
var t = test.returnType as TypeName;
returnName = t.name.name;
}
Expand Down Expand Up @@ -179,6 +176,14 @@ class Naming {
formattedName = formattedName.replaceAll("Map", "Dictionary");

switch (formattedName.toLowerCase()) {
case "float8list":
case "float16list":
case "float32list":
return "List<double>";
case "float64list":
return "List<float>";
case "int32list":
return "List<uint>";
case "httpclientresponse":
return "HttpResponseMessage";
case "shader":
Expand All @@ -189,7 +194,7 @@ class Naming {
return "NativeEngineLayer";
case "frameinfo":
return "SKCodecFrameInfo";
case "codec":
case "codec":
return "SKCodec";
case "void":
case "bool":
Expand Down Expand Up @@ -223,7 +228,7 @@ class Naming {

static String getFormattedName(String originalName, NameStyle style) {
var formattedName = originalName;
if (formattedName == null || formattedName.length == 0) {
if (formattedName == null || formattedName.length == 0) {
return "";
} else if (formattedName == "-") {
formattedName = "subtractOperator";
Expand Down
17 changes: 13 additions & 4 deletions AST/signature/classes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ class Classes {
static String printClass(ClassElement element) {
var implementWithInterface = element.isMixin || element.isAbstract;
var name = Naming.nameWithTypeParameters(element, false);

// Workaround for classes that are not correctly picked up as interfaces
if( ["PageMetrics","FixedExtentMetrics","GestureArenaEntry"].contains(name))
implementWithInterface = true;

var code = new StringBuffer();
code.writeln("");
Comments.appendComment(code, element);
Expand Down Expand Up @@ -76,15 +81,19 @@ class Classes {
var code = new StringBuffer();
var instanceName = interface.displayName;

var anyToImplement = interface.methods.any((x) => element.methods.where((y) => y.displayName == x.displayName).length == 0)
|| interface.element.fields.any((x) => element.fields.where((y) => y.displayName == x.displayName).length == 0);
var fieldsToImplement = interface.element.fields.where((x) => !x.isPrivate &&
element.fields.where((y) => y.displayName == x.displayName).length == 0 );
var methodsToImplement = interface.methods.where((x) => !x.isPrivate && element.methods.where((y) => y.displayName == x.displayName).length == 0 );

var anyToImplement = methodsToImplement.length > 0
|| fieldsToImplement.length > 0;

if (!anyToImplement)
return '';

code.writeln('$instanceName _${instanceName}Instance = new $instanceName();');

for (var method in interface.methods.where((x) => element.methods.where((y) => y.displayName == x.displayName).length == 0 ))
for (var method in methodsToImplement)
{
var methodName = Methods.getMethodName(method);
var signature = Methods.methodSignature(method, null, false, '', null, '', '');
Expand All @@ -93,7 +102,7 @@ class Classes {
code.writeln('public $signature => _${instanceName}Instance.$methodName($parameterCalls);');
}

for (var field in interface.element.fields.where((x) => element.fields.where((y) => y.displayName == x.displayName).length == 0 ))
for (var field in fieldsToImplement)
{
var typeAndName = Fields.printTypeAndName(field);
var fieldName = Fields.getFieldName(field);
Expand Down
8 changes: 5 additions & 3 deletions AST/signature/frame.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@ class Frame {
}
code.writeln("}");

// Interfaces abstract classes
for (var type in element.types.where((t) => t.isAbstract == true && t.isValidMixin == false)) {
code.writeln(Classes.printInterface(type));
// Interfaces for abstract classes
for (var type in element.types.where((t) => t.isAbstract == true && t.isValidMixin == false
// Workaround for classes that are not correctly picked up as interfaces
|| ["PageMetrics","FixedExtentMetrics","GestureArenaEntry"].contains(t.name))) {
code.writeln(Classes.printInterface(type));
}

// Add mixins and their interfaces
Expand Down
109 changes: 56 additions & 53 deletions AST/signature/methods.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import '../types.dart';

class Methods {
static bool isSameSignature(MethodElement m1, MethodElement m2) {
return methodSignature(m1, m1, false) ==
methodSignature(m2, m2, false);
return methodSignature(m1, m1, false) == methodSignature(m2, m2, false);
}

static bool overridesBaseMethod(MethodElement method, ClassElement element) {
Expand Down Expand Up @@ -52,10 +51,8 @@ class Methods {
return false;
}

static String printMethod(
MethodElement element, bool isOverride,
static String printMethod(MethodElement element, bool isOverride,
[String inheritedType = '']) {

// HACK: ignoring all ToString() methods at the moment.
if (element.name == 'toString') return "";

Expand All @@ -72,8 +69,7 @@ class Methods {
else if (element.hasProtected == true || (element.isPrivate && isOverride))
code.write("protected ");
else if (element.isPrivate == true) code.write("private ");
if (isOverride)
{
if (isOverride) {
// HACK: normally use 'override' but use `new` in case return type mismatch
// Because C# doesn't support return type covariance (yet anyway, its a proposed feature).
code.write("new ");
Expand All @@ -84,47 +80,42 @@ class Methods {
else if (element.hasOverride == false && element.isPrivate == false)
code.write("virtual ");

code.write(
methodSignature(baseMethod, element, isOverride, inheritedType));
code.write(methodSignature(baseMethod, element, isOverride, inheritedType));

code.writeln(Implementation.MethodBody(element.computeNode().body));


// HACK: Covariant type used, hence need to implement the exact interface type
// In method bodies, we need to convert and redirect this to the actual method above.
var isCovariant = false;
for (var parameter in baseMethod.parameters)
{
for (var parameter in baseMethod.parameters) {
if (parameter.isCovariant) isCovariant = true;
}

if (isCovariant && typesDifferent(element.parameters, baseMethod.parameters))
{
if (isCovariant &&
typesDifferent(element.parameters, baseMethod.parameters)) {
code.write("public new ");

code.write(
methodSignature(baseMethod, null, isOverride, inheritedType));

code.writeln(Implementation.MethodBody(element.computeNode().body));
code.write(methodSignature(baseMethod, null, isOverride, inheritedType));

code.writeln(Implementation.MethodBody(element.computeNode().body));
}

return code.toString();
}

static bool typesDifferent(List<ParameterElement> first, List<ParameterElement> other)
{
if (first.length != other.length) return true;

var count = 0;
for (var item in first)
{
if ((item.type.displayName != other[count].type.displayName)
&& other[count].type.displayName != 'T' && item.type.displayName != 'T'
&& !other[count].type.displayName.contains('<T>') && !item.type.displayName.contains('<T>'))
return true;
count += 1;
}
static bool typesDifferent(
List<ParameterElement> first, List<ParameterElement> other) {
if (first.length != other.length) return true;

var count = 0;
for (var item in first) {
if ((item.type.displayName != other[count].type.displayName) &&
other[count].type.displayName != 'T' &&
item.type.displayName != 'T' &&
!other[count].type.displayName.contains('<T>') &&
!item.type.displayName.contains('<T>')) return true;
count += 1;
}

return false;
}
Expand Down Expand Up @@ -174,10 +165,8 @@ class Methods {
return false;
}

static String getMethodName(
MethodElement element)
{
var methodName = Naming.nameWithTypeParameters(element, false);
static String getMethodName(MethodElement element) {
var methodName = Naming.nameWithTypeParameters(element, false);
if (methodName ==
Naming.nameWithTypeParameters(element.enclosingElement, false))
methodName = "Self" + methodName;
Expand All @@ -188,14 +177,15 @@ static String getMethodName(
? NameStyle.LeadingUnderscoreLowerCamelCase
: NameStyle.UpperCamelCase);

return methodName;
}
return methodName;
}

static String methodSignature(
MethodElement element,
MethodElement overridenElement,
bool isOverride,
[String inheritedType = '', InterfaceType originalMixin = null, String additionalParameter = '', String generics = '']) {
MethodElement element, MethodElement overridenElement, bool isOverride,
[String inheritedType = '',
InterfaceType originalMixin = null,
String additionalParameter = '',
String generics = '']) {
var highestMethod = overridenElement;

if (highestMethod == null) highestMethod = element;
Expand Down Expand Up @@ -226,25 +216,26 @@ static String getMethodName(
}

if (additionalParameter.isNotEmpty && parameter.isNotEmpty)
additionalParameter += ',';
additionalParameter += ',';

// HACK: A single once off hack because I'm messing something up here and don't know what
if (returnTypeName == 'Future<E>' && methodName == 'Then<R>')
methodName = 'Then<E>';
methodName = 'Then<E>';

// Cheap Hack
if (returnTypeName == 'Future<Image>')
returnTypeName = 'Future<SKImage>';
if (returnTypeName == 'Future<Image>') returnTypeName = 'Future<SKImage>';

return "${returnTypeName} ${methodName}${typeParameter}$generics($additionalParameter${parameter})";
}

static String printAutoParameters(
FunctionTypedElement element, String className, {String instanceName = "this"}) {
FunctionTypedElement element, String className,
{String instanceName = "this"}) {
return element.parameters.where((x) {
return x.isInitializingFormal == true;
}).map((p) {
var variableName = Naming.getFormattedName(p.name, NameStyle.UpperCamelCase);
var variableName =
Naming.getFormattedName(p.name, NameStyle.UpperCamelCase);

// I don't really like renaming variables, but not sure what other choice we have atm.
if (variableName == className) variableName += 'Value';
Expand Down Expand Up @@ -284,19 +275,20 @@ static String getMethodName(
if (parameterName == "")
parameterName = "p" + (method.parameters.indexOf(p) + 1).toString();

var parameterType =
Types.getParameterType(p, method, overridenMethod);
var parameterType = Types.getParameterType(p, method, overridenMethod);

if (parameterType == null) {
parameterType = "object";
}

if (parameterType == 'T' && originalMixin != null)
{

if (parameterType == 'T' && originalMixin != null) {
if (originalMixin.typeArguments[0].name.isNotEmpty)
parameterType = originalMixin.typeArguments[0].name;
}


// This is a workaround, the namespace should be added automatically
if (parameterType == 'List<Offset>') parameterType = 'List<FlutterBinding.UI.Offset>';

var parameterSignature = parameterType + " " + parameterName;

// Add keys
Expand All @@ -309,6 +301,17 @@ static String getMethodName(
if (p.isOptional) {
var defaultValue = "default(${parameterType})";

var unmodifiedDefaultValue = p.defaultValueCode;
if (unmodifiedDefaultValue != null &&
unmodifiedDefaultValue != "" &&
(unmodifiedDefaultValue == "true" ||
unmodifiedDefaultValue == "false" // bool
||
double.tryParse(unmodifiedDefaultValue) != null)) {
// numeric
defaultValue = p.defaultValueCode;
}

parameterSignature += " = ${defaultValue}";
}
return parameterSignature;
Expand Down
24 changes: 24 additions & 0 deletions AST/types.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,32 @@ class Types {
var formattedName = Naming.getFormattedTypeName(typeName);
var library = type.element.library;

if (library != null && library.displayName == 'dart.ui'){
switch(typeName){
case "Image":
case "Paint":
case "Picture":
case "Vertices":
return "SK" + typeName;
case "TextStyle":
case "PointMode":
case "RRect":
case "Paragraph":
case "Offset":
case "BlendMode":
case "Rect":
case "Color":
return "FlutterBinding.UI." + typeName;
case "List<Offset>":
return "List<FlutterBinding.UI.Offset>";
}
}

if (library != null && library.displayName == 'dart.ui' && typeName == 'Image')
return 'SKImage';

if (library != null && library.displayName == 'dart.ui' && typeName == 'TextStyle')
return 'FlutterBinding.UI.TextStyle';

if (!(type is TypeParameterType) &&
library != null &&
Expand Down
Loading

0 comments on commit 5e48e24

Please sign in to comment.