-
-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathclass.js
More file actions
135 lines (124 loc) · 3.77 KB
/
class.js
File metadata and controls
135 lines (124 loc) · 3.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/**
* Hyperloop Metabase Generator
* Copyright (c) 2015-2018 by Appcelerator, Inc.
*/
'use strict';
const util = require('./util');
const swift = require('hyperloop-metabase').swift;
function makeClass(json, cls, state) {
var entry = {
class: {
name: cls.name,
fqcn: generateFullyQualifiedClassName(cls, state),
instance_properties: [],
class_properties: [],
instance_methods: [],
class_methods: []
},
framework: cls.framework,
filename: cls.filename,
imports: {},
renderedImports: '',
superclass: cls.superclass && json.classes[cls.superclass],
state: state
};
cls.properties && Object.keys(cls.properties).sort().forEach(function (k) {
var prop;
if (!state.isGetterPropertyReferenced(k) && !state.isSetterPropertyReferenced(k)) {
return;
}
if (isClassProperty(cls.properties[k])) {
prop = util.generateClassProperty(entry, json, cls.properties[k]);
} else {
prop = util.generateProp(entry, json, cls.properties[k]);
}
if (!state.isGetterPropertyReferenced(k)) {
prop.getter = null;
}
if (!state.isSetterPropertyReferenced(k)) {
prop.setter = null;
}
if (prop.setter || prop.getter) {
if (isClassProperty(cls.properties[k])) {
entry.class.class_properties.push(prop);
} else {
entry.class.instance_properties.push(prop);
}
}
});
cls.methods && Object.keys(cls.methods).sort().forEach(function (k) {
var method = cls.methods[k];
if (!method.framework) {
method.framework = cls.framework;
}
if (shouldSkipMethodIfPropertyAvailable(k, cls)) {
return;
}
if (!state.isFunctionReferenced(method.name)) {
return;
}
if (method.instance) {
entry.class.instance_methods.push(util.generateInstanceMethod(entry, json, method));
} else {
entry.class.class_methods.push(util.generateClassMethod(entry, json, method));
}
});
entry.renderedImports = util.makeImports(json, entry.imports);
return entry;
}
/**
* Generates the appropriate fully qualified name for a class.
*
* This handles cases where we need three different class names:
* - The default Objective-C class name
* - The mangled class name for Swift classes
* - A combination of FrameworkName.ClassName for Objective-C classes that were
* imported from the Objective-C interface header of a Swift module.
*
* @param {Object} cls Class metadata object
* @param {Object} state Parser state
* @return {String} Fully qualified class name
*/
function generateFullyQualifiedClassName(cls, state) {
var fullyQualifiedClassName = cls.name;
if (cls.language === 'swift') {
fullyQualifiedClassName = swift.generateSwiftMangledClassName(state.appName, cls.name);
} else if (cls.filename && cls.filename.endsWith(cls.framework + '-Swift.h')) {
fullyQualifiedClassName = cls.framework + '.' + cls.name;
}
return fullyQualifiedClassName;
}
/**
* Decides wether a method should be skipped in favor of its matching property.
*
* Return true for methods that have the same name as a property (getter method)
*
* @param {String} methodKey
* @param {Object} classMetadata
* @param {ParserState} state
* @return {Boolean}
*/
function shouldSkipMethodIfPropertyAvailable(methodKey, classMetadata) {
var classMethodMetadata = classMetadata[methodKey];
var matchingPropertyMetadata = classMetadata.properties && classMetadata.properties[methodKey];
if (!matchingPropertyMetadata) {
return false;
}
return true;
}
/**
* Returns wether a property is a class property or not
*
* @param {Object} propertyMetadata
* @return {Boolean}
*/
function isClassProperty(propertyMetadata) {
return propertyMetadata.attributes && propertyMetadata.attributes.indexOf('class') !== -1;
}
/**
* Generates the source template data for a class file
*/
function generate(json, cls, state) {
return makeClass(json, cls, state);
}
exports.generate = generate;