Skip to content

Commit fbeac02

Browse files
committed
Workaround for type conversion bug
AssemblyScript#429 This fix changes bindings generation to only generate each encode / decode function once, so that they don’t clash names.
1 parent 1817b03 commit fbeac02

File tree

3 files changed

+147
-464
lines changed

3 files changed

+147
-464
lines changed

src/definitions.ts

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import {
3333
import {
3434
indent
3535
} from "./util";
36-
import { Source, NodeKind, ImportStatement } from "./ast";
36+
import { Source, NodeKind, ImportStatement, DeclarationStatement, ExportStatement } from "./ast";
3737

3838
/** Walker base class. */
3939
abstract class ExportsWalker {
@@ -143,6 +143,7 @@ export class NEARBindingsBuilder extends ExportsWalker {
143143
private generatedDecodeFunctions = new Set<string>();
144144
private exportedClasses: Class[] = [];
145145
private exportedFunctions: Function[] = [];
146+
private filesByImport = new Map<string, string>();
146147

147148
static build(program: Program): string {
148149
return new NEARBindingsBuilder(program).build();
@@ -317,7 +318,7 @@ export class NEARBindingsBuilder extends ExportsWalker {
317318
}`);
318319
} else {
319320
this.sb.push(`pushObject(name: string): bool {
320-
${valuePrefix}.push(__near_decode_${this.encodeType(fieldType)}(this.buffer, this.decoder.state));
321+
${valuePrefix}.push(<${fieldType}>__near_decode_${this.encodeType(fieldType)}(this.buffer, this.decoder.state));
321322
return false;
322323
}
323324
pushArray(name: string): bool {
@@ -326,12 +327,13 @@ export class NEARBindingsBuilder extends ExportsWalker {
326327
this.handledRoot = true;
327328
return true;
328329
}
329-
${valuePrefix}.push(__near_decode_${this.encodeType(fieldType)}(this.buffer, this.decoder.state));
330+
${valuePrefix}.push(<${fieldType}>__near_decode_${this.encodeType(fieldType)}(this.buffer, this.decoder.state));
330331
return false;
331332
}`);
332333
}
333334
}
334335

336+
335337
private generateEncodeFunction(type: Type) {
336338
if (!type.classReference) {
337339
return;
@@ -343,6 +345,11 @@ export class NEARBindingsBuilder extends ExportsWalker {
343345
}
344346
this.generatedEncodeFunctions.add(typeName);
345347

348+
let methodName = `__near_encode_${typeName}`;
349+
if (this.tryUsingImport(type, methodName)) {
350+
return;
351+
}
352+
346353
if (this.isArrayType(type)) {
347354
// Array
348355
this.generateEncodeFunction(type.classReference.typeArguments![0]);
@@ -374,6 +381,24 @@ export class NEARBindingsBuilder extends ExportsWalker {
374381
this.sb.push("}");
375382
}
376383

384+
private tryUsingImport(type: Type, methodName: string): bool {
385+
let importedFile = this.filesByImport.get(type.classReference!.simpleName);
386+
if (importedFile) {
387+
if (this.hasExport(importedFile, methodName)) {
388+
this.sb.push(`import { ${methodName} } from "${importedFile}";`);
389+
return true;
390+
}
391+
}
392+
return false;
393+
}
394+
395+
private hasExport(importedFile: string, name: string): bool {
396+
let importedSource = this.program.sources.filter(
397+
s => "./" + s.normalizedPath == importedFile + ".ts")[0];
398+
399+
return this.getExports(importedSource).filter(d => d.name.text == name).length > 0;
400+
}
401+
377402
private generateHandler(type: Type) {
378403
let typeName = this.encodeType(type);
379404
this.sb.push(`export class __near_JSONHandler_${typeName} extends ThrowingJSONHandler {
@@ -416,6 +441,11 @@ export class NEARBindingsBuilder extends ExportsWalker {
416441
}
417442
this.generatedDecodeFunctions.add(typeName);
418443

444+
let methodName = `__near_decode_${typeName}`;
445+
if (this.tryUsingImport(type, methodName)) {
446+
return;
447+
}
448+
419449
this.generateHandler(type);
420450
if (this.isArrayType(type)) {
421451
// Array
@@ -529,18 +559,31 @@ export class NEARBindingsBuilder extends ExportsWalker {
529559
}
530560

531561
private copyImports(mainSource: Source): any {
532-
let imports = <ImportStatement[]>mainSource.statements
533-
.filter(statement => statement.kind == NodeKind.IMPORT);
534-
535-
imports.forEach(statement => {
562+
this.getImports(mainSource).forEach(statement => {
536563
if (statement.declarations) {
537564
let declarationsStr = statement.declarations!
538565
.map(declaration => `${declaration.externalName.text} as ${declaration.name.text}`)
539566
.join(",");
540567
this.sb.push(`import {${declarationsStr}} from "${statement.path.value}";`);
568+
statement.declarations.forEach(d => {
569+
this.filesByImport.set(d.name.text, statement.path.value);
570+
});
541571
}
542572
});
543573
}
574+
575+
private getImports(source: Source): ImportStatement[] {
576+
return <ImportStatement[]>source.statements
577+
.filter(statement => statement.kind == NodeKind.IMPORT);
578+
}
579+
580+
private getExports(source: Source): DeclarationStatement[] {
581+
let declarations = <DeclarationStatement[]>source.statements
582+
.filter(statement =>
583+
statement.kind == NodeKind.FUNCTIONDECLARATION ||
584+
statement.kind == NodeKind.CLASSDECLARATION);
585+
return declarations.filter(d => d.isTopLevelExport);
586+
}
544587
}
545588

546589
/** A WebIDL definitions builder. */

0 commit comments

Comments
 (0)