Skip to content
This repository has been archived by the owner on Dec 14, 2017. It is now read-only.

Commit

Permalink
Merge pull request #233 from yjbanov/sync-v0.2
Browse files Browse the repository at this point in the history
null-safe errors; global in subclasses; servicePath fix; nested files; version in library name
  • Loading branch information
yjbanov committed Aug 22, 2014
2 parents f98f3b3 + 631ca7b commit 969cf8b
Show file tree
Hide file tree
Showing 15 changed files with 174 additions and 67 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ test/benchmark_html.dart.*
test/integration/bankapi
test/integration/apigen_test/build
test/integration/transformer_test/build
pub-server
3 changes: 2 additions & 1 deletion lib/generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Future generateStreamyClientPackage(
}
}

var packageDirPath = '${outputDir.path}/${packageName}';
var packageDirPath = outputDir.path;
var libDirPath = '${packageDirPath}/lib';
new io.Directory(libDirPath).createSync(recursive: true);
var basePath = '${libDirPath}/${client.config.outputPrefix}';
Expand All @@ -59,6 +59,7 @@ Future generateStreamyClientPackage(
if (dartFile == null) return new Future.value();
var fileName = '${client.config.outputPrefix}${suffix}.dart';
var file = new io.File(path.join(libDirPath, fileName));
new io.Directory(path.dirname(file.path)).createSync(recursive: true);
file.writeAsStringSync(dartFile.render());
}

Expand Down
121 changes: 74 additions & 47 deletions lib/generator/emitter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ class Emitter {
final Map<String, mustache.Template> templates;

Emitter(this.config, this.templates);


static final BASE_PREFIX = '_streamy_base_';

static final List<String> TEMPLATES = const [
'lazy_resource_getter',
'map',
Expand Down Expand Up @@ -77,13 +79,13 @@ class Emitter {
var objectFile, objectPrefix;
var dispatchFile, dispatchPrefix;
var libPrefix = api.name;
if (api.httpConfig != null && api.httpConfig.version != null) {
libPrefix = "$libPrefix.${api.httpConfig.version}";
if (api.httpConfig != null) {
libPrefix = "$libPrefix";
}
rootFile = new DartLibrary(libPrefix)
..imports['package:streamy/streamy.dart'] = 'streamy'
..imports['package:fixnum/fixnum.dart'] = 'fixnum'
..imports[config.baseImport] = 'base'
..imports[config.baseImport] = BASE_PREFIX
..imports['dart:async'] = null;
var out = [rootFile];
switch (config.splitLevel) {
Expand Down Expand Up @@ -122,24 +124,24 @@ class Emitter {
resourceFile.imports
..['package:streamy/streamy.dart'] = 'streamy'
..['package:fixnum/fixnum.dart'] = 'fixnum'
..[config.baseImport] = 'base'
..[config.baseImport] = BASE_PREFIX
..[importPath('requests.dart')] = 'requests'
..[importPath('objects.dart')] = 'objects';
requestFile.imports
..['package:streamy/streamy.dart'] = 'streamy'
..['package:fixnum/fixnum.dart'] = 'fixnum'
..[config.baseImport] = 'base'
..[config.baseImport] = BASE_PREFIX
..[importPath('objects.dart')] = 'objects'
..[importPath('dispatch.dart')] = 'dispatch'
..['dart:async'] = null;
objectFile.imports
..['package:streamy/streamy.dart'] = 'streamy'
..['package:fixnum/fixnum.dart'] = 'fixnum'
..[config.baseImport] = 'base';
..[config.baseImport] = BASE_PREFIX;
dispatchFile.imports
..['package:streamy/streamy.dart'] = 'streamy'
..['package:fixnum/fixnum.dart'] = 'fixnum'
..[config.baseImport] = 'base'
..[config.baseImport] = BASE_PREFIX
..[importPath('objects.dart')] = 'objects';
out.addAll([resourceFile, requestFile, objectFile, dispatchFile]);
resourceFile.imports.addAll(api.imports);
Expand Down Expand Up @@ -169,7 +171,7 @@ class Emitter {

List<DartClass> processRoot(Api api, String resourcePrefix, String dispatchPrefix) {
// Create the resource mixin class.
var resourceMixin = new DartClass('${toProperIdentifier(api.name)}ResourcesMixin');
var resourceMixin = new DartClass('${_makeClassName(api.name)}ResourcesMixin');
if (api.description != null) {
resourceMixin.comments.addAll(splitStringAcrossLines(api.description));
}
Expand All @@ -178,10 +180,9 @@ class Emitter {
var getterTemplate = _template('lazy_resource_getter');
api.resources.forEach((name, resource) {
// Backing field.
var resName = toProperIdentifier(resource.name);
var lcResName = toProperIdentifier(resource.name, firstLetter: false);
var lcResName = _makePropertyName(resource.name);
var fieldName = '_$lcResName';
var type = new DartType('${resName}Resource',
var type = new DartType('${_makeClassName(resource.name)}Resource',
resourcePrefix, const []);
var field = new DartSimpleField(fieldName, type);
resourceMixin.fields.add(field);
Expand All @@ -198,8 +199,8 @@ class Emitter {
}
final marshallerType = new DartType('Marshaller', dispatchPrefix, const []);
var mixinType = new DartType.from(resourceMixin);
var txClassName = toProperIdentifier('${api.name}Transaction');
var root = new DartClass(toProperIdentifier(api.name), baseClass: baseType)
var txClassName = _makeClassName('${api.name}Transaction');
var root = new DartClass(_makeClassName(api.name), baseClass: baseType)
..mixins.add(mixinType)
..fields.add(new DartSimpleField('marshaller', marshallerType, isFinal: true))
..fields.add(new DartSimpleField('requestHandler', streamyImport('RequestHandler'), isFinal: true))
Expand All @@ -213,9 +214,6 @@ class Emitter {
var ctorData = {
'http': api.httpConfig != null
};
if (api.httpConfig != null) {
ctorData['servicePath'] = api.httpConfig.servicePath;
}
var ctor = new DartConstructor(root.name, body: new DartTemplateBody(
_template('root_constructor'), ctorData))
..parameters.add(new DartParameter('requestHandler',
Expand Down Expand Up @@ -273,8 +271,7 @@ class Emitter {

DartClass processResource(Resource resource, String requestPrefix,
String objectPrefix) {
var name = toProperIdentifier(resource.name);
var clazz = new DartClass('${toProperIdentifier(resource.name)}Resource');
var clazz = new DartClass('${_makeClassName(resource.name)}Resource');
var requestMethodTemplate = _template('request_method');

// Set up a _root field for the implementation RequestHandler, and a
Expand Down Expand Up @@ -316,10 +313,10 @@ class Emitter {
}

var requestType = new DartType(
'${toProperIdentifier(resource.name)}${toProperIdentifier(method.name)}Request',
'${_makeClassName(resource.name)}${_makeClassName(method.name)}Request',
requestPrefix, const []);

var m = new DartMethod(toProperIdentifier(method.name, firstLetter: false), requestType,
var m = new DartMethod(_makeMethodName(method.name), requestType,
new DartTemplateBody(requestMethodTemplate, {
'requestType': requestType,
'parameters': pnames
Expand All @@ -345,15 +342,17 @@ class Emitter {
.expand((resource) => resource
.methods
.values
.map((method) => processRequest(api, toProperIdentifier(resource.name), method, objectPrefix, dispatchPrefix))
.map((method) => processRequest(api, _makeClassName(resource.name),
method, objectPrefix, dispatchPrefix))
)
.toList(growable: false);

DartClass processRequest(Api api, String resourceName, Method method, String objectPrefix, String dispatchPrefix) {

DartClass processRequest(Api api, String resourceClassName, Method method,
String objectPrefix, String dispatchPrefix) {
var paramGetter = _template('request_param_getter');
var paramSetter = _template('request_param_setter');
var methodName = toProperIdentifier(method.name);
var clazz = new DartClass('$resourceName${methodName}Request',
var methodName = _makeClassName(method.name);
var clazz = new DartClass('$resourceClassName${methodName}Request',
baseClass: streamyImport('HttpRequest'));

// Determine payload type.
Expand Down Expand Up @@ -396,10 +395,10 @@ class Emitter {
method.parameters.forEach((name, param) {
var type = toDartType(param.typeRef, objectPrefix);
clazz.fields.add(
new DartComplexField(toProperIdentifier(name, firstLetter: false), type,
new DartComplexField(_makePropertyName(name), type,
new DartTemplateBody(paramGetter, {'name': name}),
new DartTemplateBody(paramSetter, {'name': name})));
clazz.methods.add(new DartMethod(toProperIdentifier('remove_$name', firstLetter: false), type,
clazz.methods.add(new DartMethod(_makeRemoverName(name), type,
new DartTemplateBody(_template('request_remove'), {'name': name})));
});

Expand Down Expand Up @@ -471,15 +470,15 @@ class Emitter {
if (responseType != null && api.httpConfig != null) {
clazz.methods.add(new DartMethod('unmarshalResponse', responseType,
new DartTemplateBody(_template('request_unmarshal_response'), {
'name': toProperIdentifier(method.responseType.schemaClass)
'name': _makeClassName((method.responseType as SchemaTypeRef).schemaClass)
}))
..parameters.add(new DartParameter('data', new DartType('Map', null, const []))));
}

if (method.payloadType != null) {
clazz.methods.add(new DartMethod('marshalPayload', new DartType('Map'),
new DartTemplateBody(_template('request_marshal_payload'), {
'name': toProperIdentifier(method.payloadType.schemaClass)
'name': _makeClassName((method.payloadType as SchemaTypeRef).schemaClass)
})));
}
}
Expand Down Expand Up @@ -546,8 +545,8 @@ class Emitter {
}

SchemaDefinition processSchema(Schema schema) {
var base = new DartType(config.baseClass, 'base', const []);
var clazz = new DartClass(toProperIdentifier(schema.name), baseClass: base);
var base = new DartType(config.baseClass, BASE_PREFIX, const []);
var clazz = new DartClass(_makeClassName(schema.name), baseClass: base);
clazz.mixins.addAll(schema.mixins.map((mixin) => toDartType(mixin, '')));

var globalFnDef = null;
Expand All @@ -560,12 +559,17 @@ class Emitter {
clazz.methods.add(new DartConstructor(clazz.name, body: new DartTemplateBody(
ctor, {
'mapBacked': config.mapBackedFields,
'wrap': false
'wrap': false,
'basePrefix': BASE_PREFIX,
})));

if (config.mapBackedFields) {
clazz.methods.add(new DartConstructor(clazz.name, named: 'wrap',
body: new DartTemplateBody(ctor, {'mapBacked': true, 'wrap': true}))
body: new DartTemplateBody(ctor, {
'mapBacked': true,
'wrap': true,
'basePrefix': BASE_PREFIX,
}))
..parameters.add(new DartParameter('map', new DartType.map(const DartType.string(), const DartType.dynamic()))));
}

Expand All @@ -589,15 +593,15 @@ class Emitter {

schema.properties.forEach((_, field) {
// Add getter and setter, delegating to map access.
var name = toProperIdentifier(field.name, firstLetter: false);
var name = _makePropertyName(field.name);
var type = toDartType(field.typeRef, null);
if (config.mapBackedFields) {
var f = new DartComplexField(name, type,
new DartTemplateBody(getter, {'name': field.name}),
new DartTemplateBody(setter, {'name': field.name}));
clazz.fields.add(f);
if (config.removers) {
var r = new DartMethod('remove${toProperIdentifier(field.name)}', type,
var r = new DartMethod(_makeRemoverName(field.name), type,
new DartTemplateBody(remove, {'name': field.name}));
clazz.methods.add(r);
}
Expand All @@ -616,6 +620,10 @@ class Emitter {
clazz.methods.add(new DartMethod('patch', schemaType,
new DartTemplateBody(_template('object_patch'), {'type': schemaType})));
}
if (config.global) {
clazz.methods.add(new DartComplexField.getterOnly('streamyType',
new DartType('Type'), new DartConstantBody('=> ${clazz.name};')));
}

addApiType(clazz);

Expand All @@ -631,16 +639,17 @@ class Emitter {
doubleFields.add(name);
break;
case 'schema':
entityFields[name] = typeRef.schemaClass;
entityFields[name] = (typeRef as SchemaTypeRef).schemaClass;
break;
case 'list':
_accumulateMarshallingTypes(name, typeRef.subType, int64Fields, doubleFields, entityFields);
_accumulateMarshallingTypes(name, (typeRef as ListTypeRef).subType,
int64Fields, doubleFields, entityFields);
break;
}
}

void processSchemaForMarshaller(DartClass clazz, Schema schema, String objectPrefix) {
var name = toProperIdentifier(schema.name);
var name = _makeClassName(schema.name);
var type = new DartType(name, objectPrefix, const []);
var rt = new DartType.map(const DartType.string(), const DartType.dynamic());
var data = {
Expand All @@ -657,17 +666,25 @@ class Emitter {
schema
.properties
.forEach((_, field) {
_accumulateMarshallingTypes(field.name, field.typeRef, int64Fields, doubleFields, entityFields);
allFields.add({'key': field.name, 'identifier': toProperIdentifier(field.name, firstLetter: false)});
_accumulateMarshallingTypes(field.name, field.typeRef, int64Fields,
doubleFields, entityFields);
allFields.add({
'key': field.name,
'identifier': _makePropertyName(field.name),
});
});

var stringList = new DartType.list(const DartType.string());
var serialMap = new DartType('Map');
if (int64Fields.isNotEmpty) {
clazz.fields.add(new DartSimpleField('_int64s$name', stringList, isStatic: true, isFinal: true, initializer: stringListBody(int64Fields)));
clazz.fields.add(new DartSimpleField('_int64s$name', stringList,
isStatic: true, isFinal: true,
initializer: stringListBody(int64Fields)));
}
if (doubleFields.isNotEmpty) {
clazz.fields.add(new DartSimpleField('_doubles$name', stringList, isStatic: true, isFinal: true, initializer: stringListBody(doubleFields)));
clazz.fields.add(new DartSimpleField('_doubles$name', stringList,
isStatic: true, isFinal: true,
initializer: stringListBody(doubleFields)));
}

var fieldMapping = {};
Expand All @@ -687,10 +704,17 @@ class Emitter {
if (entityFields.isNotEmpty) {
var data = [];
entityFields.forEach((name, schema) {
data.add({'key': name, 'value': '_handle${toProperIdentifier(schema)}'});
data.add({
'key': name,
'value': _makeHandlerName(schema),
});
});
clazz.fields.add(new DartComplexField.getterOnly('_entities$name', rt,
new DartTemplateBody(_template('map'), {'pairs': data, 'getter': true, 'const': false})));
new DartTemplateBody(_template('map'), {
'pairs': data,
'getter': true,
'const': false,
})));
}
var serializerConfig = {
'entity': type,
Expand All @@ -703,6 +727,7 @@ class Emitter {
'doubles': doubleFields,
'hasEntities': entityFields.isNotEmpty,
'hasFieldMapping': fieldMapping.isNotEmpty,
'basePrefix': BASE_PREFIX,
};
clazz.methods.add(new DartMethod('marshal$name', rt,
new DartTemplateBody(marshal, serializerConfig))
Expand Down Expand Up @@ -755,7 +780,7 @@ class Emitter {
if (ref is ListTypeRef) {
return new DartType.list(toDartType(ref.subType, objectPrefix));
} else if (ref is SchemaTypeRef) {
return new DartType(toProperIdentifier(ref.schemaClass), objectPrefix, const []);
return new DartType(_makeClassName(ref.schemaClass), objectPrefix, const []);
} else {
switch (ref.base) {
case 'int64':
Expand All @@ -773,7 +798,9 @@ class Emitter {
case 'number':
return const DartType.double();
case 'external':
return new DartType(ref.type, ref.importedFrom, const []);
ExternalTypeRef externalTypeRef = ref;
return new DartType(externalTypeRef.type,
externalTypeRef.importedFrom, const []);
default:
throw new Exception('Unhandled API type: $ref');
}
Expand Down
2 changes: 1 addition & 1 deletion lib/generator/service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ void _parseService(Api api, String importPath, analyzer.ClassDeclaration clazz)
var method = new Method(m.name.name, new Path('/'), '', null, ref);
res.methods[method.name] = method;
// Need a request class for the method.
var name = '${res.name}${toProperIdentifier(m.name.name)}Request';
var name = '${res.name}${_makeClassName(m.name.name)}Request';
m
.parameters
.parameters
Expand Down
Loading

0 comments on commit 969cf8b

Please sign in to comment.