UNPKG

dts2as

Version:

A command line tool that converts TypeScript definitions (d.ts files) to ActionScript 3 classes and interfaces

512 lines (508 loc) 20.5 kB
"use strict"; /* Copyright 2015-2017 Bowler Hat LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ Object.defineProperty(exports, "__esModule", { value: true }); var as3 = require("./as3"); var NEW_LINE = "\n"; function arrayValues(array) { var values = []; array.forEach(function (item) { if (values.indexOf(item) < 0) { values.push(item); } }); return values; } var default_1 = (function () { function default_1(types) { this.moduleMetadata = false; this._types = types; } default_1.prototype.emitClass = function (as3Class) { var _this = this; var className = as3Class.name; var superClass = as3Class.superClass; var interfaces = as3Class.interfaces; var constructorMethod = this.getConstructorMethod(as3Class); var classOutput = this.emitStartPackage(as3Class.packageName); var imports = []; if (superClass && as3.requiresImport(superClass, as3Class)) { imports.push(superClass.getFullyQualifiedName()); } if (interfaces.length > 0) { interfaces.forEach(function (as3Interface) { if (!as3.requiresImport(as3Interface, as3Class)) { return; } imports.push(as3Interface.getFullyQualifiedName()); }); } if (constructorMethod) { this.addParametersImports(constructorMethod, as3Class, imports); } this.addMemberImports(as3Class, imports); for (var _i = 0, _a = arrayValues(imports); _i < _a.length; _i++) { var as3Import = _a[_i]; classOutput += "import " + as3Import + ";"; classOutput += NEW_LINE; } classOutput += this.emitModuleMetadata(as3Class); classOutput += as3Class.accessLevel; if (as3Class.dynamic) { classOutput += " dynamic"; } classOutput += " class "; classOutput += className; if (superClass) { classOutput += " extends "; classOutput += this.getNameToEmit(superClass, as3Class); } if (interfaces.length > 0) { classOutput += " implements "; interfaces.forEach(function (as3Interface, index) { if (index > 0) { classOutput += ", "; } classOutput += _this.getNameToEmit(as3Interface, as3Class); }); } classOutput += NEW_LINE; classOutput += "{" + NEW_LINE; //static properties and methods first var needsExtraNewLine = false; as3Class.properties.forEach(function (property) { if (!property.isStatic) { return; } classOutput += _this.emitProperty(property, as3Class); classOutput += NEW_LINE; needsExtraNewLine = true; }); if (needsExtraNewLine) { classOutput += NEW_LINE; } needsExtraNewLine = false; as3Class.methods.forEach(function (method) { if (!method.isStatic) { return; } classOutput += _this.emitMethod(method, as3Class); classOutput += NEW_LINE; needsExtraNewLine = true; }); if (needsExtraNewLine) { classOutput += NEW_LINE; } classOutput += "public function "; classOutput += className; if (constructorMethod) { classOutput += this.emitParameters(constructorMethod, as3Class); if (superClass) { classOutput += " {"; var superConstructorMethod = this.getConstructorMethod(superClass); if (superConstructorMethod) { classOutput += " super("; var params = superConstructorMethod.parameters; for (var i = 0, paramCount = params.length; i < paramCount; i++) { var param = params[i]; if (i > 0) { classOutput += ", "; } classOutput += as3.getDefaultReturnValueForType(param.type); } classOutput += "); "; } classOutput += "}"; } else { classOutput += " {}"; } classOutput += NEW_LINE; } else { classOutput += "() {}" + NEW_LINE; } classOutput += NEW_LINE; needsExtraNewLine = false; as3Class.properties.forEach(function (property) { if (property.isStatic || as3.requiresClassOverride(property, as3Class)) { return; } classOutput += _this.emitProperty(property, as3Class); classOutput += NEW_LINE; needsExtraNewLine = true; }); if (needsExtraNewLine) { classOutput += NEW_LINE; } needsExtraNewLine = false; as3Class.methods.forEach(function (method) { if (method.isStatic || as3.requiresClassOverride(method, as3Class)) { return; } classOutput += _this.emitMethod(method, as3Class); classOutput += NEW_LINE; }); //end class classOutput += "}" + NEW_LINE; classOutput += this.emitEndPackage(); return classOutput; }; default_1.prototype.emitInterface = function (as3Interface) { var _this = this; var interfaceName = as3Interface.name; var interfaces = as3Interface.interfaces; var interfaceOutput = this.emitStartPackage(as3Interface.packageName); var imports = []; if (interfaces.length > 0) { interfaces.forEach(function (otherInterface) { if (!as3.requiresImport(otherInterface, as3Interface)) { return; } imports.push(otherInterface.getFullyQualifiedName()); }); } this.addMemberImports(as3Interface, imports); for (var _i = 0, _a = arrayValues(imports); _i < _a.length; _i++) { var as3Import = _a[_i]; interfaceOutput += "import " + as3Import + ";"; interfaceOutput += NEW_LINE; } interfaceOutput += as3Interface.accessLevel; interfaceOutput += " interface "; interfaceOutput += interfaceName; if (interfaces.length > 0) { interfaceOutput += " extends "; interfaces.forEach(function (otherInterface, index) { if (index > 0) { interfaceOutput += ", "; } interfaceOutput += _this.getNameToEmit(otherInterface, as3Interface); }); } interfaceOutput += NEW_LINE; interfaceOutput += "{" + NEW_LINE; as3Interface.properties.forEach(function (property) { if (as3.requiresInterfaceOverride(property, as3Interface)) { return; } interfaceOutput += _this.emitProperty(property, as3Interface); interfaceOutput += NEW_LINE; }); as3Interface.methods.forEach(function (method) { if (as3.requiresInterfaceOverride(method, as3Interface)) { return; } interfaceOutput += _this.emitMethod(method, as3Interface); interfaceOutput += NEW_LINE; }); //end class interfaceOutput += "}" + NEW_LINE; interfaceOutput += this.emitEndPackage(); return interfaceOutput; }; default_1.prototype.emitPackageFunction = function (as3PackageFunction) { var imports = []; this.addMethodImport(as3PackageFunction, as3PackageFunction, imports); var packageFunctionOutput = this.emitStartPackage(as3PackageFunction.packageName); for (var _i = 0, _a = arrayValues(imports); _i < _a.length; _i++) { var as3Import = _a[_i]; packageFunctionOutput += "import " + as3Import + ";"; packageFunctionOutput += NEW_LINE; } packageFunctionOutput += this.emitModuleMetadata(as3PackageFunction); packageFunctionOutput += this.emitMethod(as3PackageFunction, as3PackageFunction); packageFunctionOutput += NEW_LINE; packageFunctionOutput += this.emitEndPackage(); return packageFunctionOutput; }; default_1.prototype.emitPackageVariable = function (as3PackageVariable) { var imports = []; this.addPropertyImport(as3PackageVariable, as3PackageVariable, imports); var packageVariableOutput = this.emitStartPackage(as3PackageVariable.packageName); for (var _i = 0, _a = arrayValues(imports); _i < _a.length; _i++) { var as3Import = _a[_i]; packageVariableOutput += "import " + as3Import + ";"; packageVariableOutput += NEW_LINE; } packageVariableOutput += this.emitModuleMetadata(as3PackageVariable); packageVariableOutput += this.emitVariable(as3PackageVariable, as3PackageVariable); packageVariableOutput += NEW_LINE; packageVariableOutput += this.emitEndPackage(); return packageVariableOutput; }; default_1.prototype.emitNamespace = function (as3Namespace) { var namespaceName = as3Namespace.name; var packageName = as3Namespace.packageName; var accessLevel = as3Namespace.accessLevel; var uri = as3Namespace.uri; var namespaceOutput = this.emitStartPackage(packageName); namespaceOutput += accessLevel; namespaceOutput += " namespace "; namespaceOutput += namespaceName; namespaceOutput += " = \""; namespaceOutput += uri; namespaceOutput += "\";"; namespaceOutput += NEW_LINE; namespaceOutput += this.emitEndPackage(); return namespaceOutput; }; default_1.prototype.getNameToEmit = function (target, scope) { if (!target) { return "*"; } var targetName = target.name; var scopeName = scope.name; var typeNameHasConflict = false; if (scope instanceof as3.InterfaceDefinition || scope instanceof as3.ClassDefinition) { typeNameHasConflict = scope.getProperty(targetName) !== null || scope.getMethod(targetName) !== null; if (typeNameHasConflict === false && scopeName === targetName) { //if the type name is the same as the scope name, we need to //check if an interface or the super class also has the same //name, but appears in another package typeNameHasConflict = scope.interfaces.some(function (otherInterface) { return otherInterface.name === targetName; }); if (typeNameHasConflict === false && scope instanceof as3.ClassDefinition) { typeNameHasConflict = scope.superClass && scope.superClass.name === targetName; } } } if (typeNameHasConflict) { var fullyQualifiedName = target.getFullyQualifiedName(); //the AS3 compiler doesn't like giving a member a type that matches //the name of any of the members. if (targetName === fullyQualifiedName) { //if the type is in the top level package, we need to fall back //to * because there's no fully-qualified name to reference return "*"; } return fullyQualifiedName; } var targetPackageName = target.packageName; if (!targetPackageName) { return targetName; } //if there's a top level definition with the same name, another symbol //in the same package as the scope with the same name, or if the scope //has the same name, we need to be specific. var nameInPackage = targetName; var scopePackageName = scope.packageName; if (targetName === scopeName && targetPackageName !== scopePackageName) { return target.getFullyQualifiedName(); } if (nameInPackage.length > 0) { nameInPackage = scopePackageName + nameInPackage; } if (as3.getDefinitionByName(targetName, this._types) === null || (targetPackageName !== scopePackageName && as3.getDefinitionByName(nameInPackage, this._types) === null)) { return targetName; } return target.getFullyQualifiedName(); }; default_1.prototype.addMemberImports = function (as3Type, imports) { var _this = this; as3Type.properties.forEach(function (as3Property) { _this.addPropertyImport(as3Property, as3Type, imports); }); as3Type.methods.forEach(function (as3Method) { _this.addMethodImport(as3Method, as3Type, imports); }); }; default_1.prototype.addPropertyImport = function (as3Property, as3Type, imports) { var propertyType = as3Property.type; if (!as3.requiresImport(propertyType, as3Type)) { return; } imports.push(propertyType.getFullyQualifiedName()); }; default_1.prototype.addMethodImport = function (as3Method, as3Type, imports) { var methodType = as3Method.type; if (as3.requiresImport(methodType, as3Type)) { imports.push(methodType.getFullyQualifiedName()); } this.addParametersImports(as3Method, as3Type, imports); }; default_1.prototype.addParametersImports = function (as3Function, as3Type, imports) { var params = as3Function.parameters; if (!params) { return; } params.forEach(function (parameter) { var parameterType = parameter.type; if (as3.requiresImport(parameterType, as3Type)) { imports.push(parameterType.getFullyQualifiedName()); } }); }; default_1.prototype.emitMethod = function (as3Method, scope) { var methodName = as3Method.name; var methodType = as3Method.type; var accessLevel = as3Method.accessLevel; var isStatic = as3Method.isStatic; var isInterface = scope instanceof as3.InterfaceDefinition; var methodOutput = "function "; if (isStatic) { methodOutput = "static " + methodOutput; } if (!isInterface && accessLevel !== null) { methodOutput = accessLevel + " " + methodOutput; } methodOutput += methodName; methodOutput += this.emitParameters(as3Method, scope); methodOutput += ":"; methodOutput += this.getNameToEmit(methodType, scope); if (isInterface) { methodOutput += ";"; } else { if (methodType !== null && methodType.getFullyQualifiedName() !== as3.BuiltIns[as3.BuiltIns.void]) { methodOutput += " { return "; methodOutput += as3.getDefaultReturnValueForType(methodType); methodOutput += "; }"; } else { if (!isInterface) { methodOutput += " {}"; } } } return methodOutput; }; default_1.prototype.emitProperty = function (as3Property, scope) { var propertyName = as3Property.name; var propertyType = as3Property.type; var accessLevel = as3Property.accessLevel; var isStatic = as3Property.isStatic; var isInterface = scope instanceof as3.InterfaceDefinition; var getterOutput = "function get "; if (isStatic) { getterOutput = "static" + " " + getterOutput; } if (!isInterface && accessLevel !== null) { getterOutput = accessLevel + " " + getterOutput; } getterOutput += propertyName; getterOutput += "():"; getterOutput += this.getNameToEmit(propertyType, scope); if (isInterface) { getterOutput += ";"; } else { getterOutput += " { return "; getterOutput += as3.getDefaultReturnValueForType(propertyType); getterOutput += "; }"; } getterOutput += NEW_LINE; var setterOutput = "function set "; if (isStatic) { setterOutput = "static" + " " + setterOutput; } if (!isInterface && accessLevel !== null) { setterOutput = accessLevel + " " + setterOutput; } setterOutput += propertyName; setterOutput += "(value:"; setterOutput += this.getNameToEmit(propertyType, scope); setterOutput += "):" + as3.BuiltIns[as3.BuiltIns.void]; if (isInterface) { setterOutput += ";"; } else { setterOutput += " {}"; } return getterOutput + setterOutput; }; default_1.prototype.emitVariable = function (as3Property, scope) { var propertyName = as3Property.name; var propertyType = as3Property.type; var accessLevel = as3Property.accessLevel; var isConstant = as3Property.isConstant; var propertyOutput = accessLevel; if (isConstant) { propertyOutput += " const "; } else { propertyOutput += " var "; } propertyOutput += propertyName; propertyOutput += ":"; propertyOutput += this.getNameToEmit(propertyType, scope); if (isConstant) { propertyOutput += " = 0"; } propertyOutput += ";"; propertyOutput += NEW_LINE; return propertyOutput; }; default_1.prototype.emitModuleMetadata = function (as3Type) { var moduleName = as3Type.moduleName; if (this.moduleMetadata && moduleName) { return "[JSModule(name=\"" + moduleName + "\")]" + NEW_LINE; } return ""; }; default_1.prototype.emitStartPackage = function (packageName) { var startPackage = "// generated by dts2as from NextGenActionScript.com" + NEW_LINE; startPackage += "package " + packageName + NEW_LINE + "{" + NEW_LINE; return startPackage; }; default_1.prototype.emitEndPackage = function () { return "}"; }; default_1.prototype.emitParameters = function (as3Function, scope) { var parameters = as3Function.parameters; var signatureOutput = "("; if (parameters) { for (var i = 0, count = parameters.length; i < count; i++) { if (i > 0) { signatureOutput += ", "; } var parameter = parameters[i]; if (parameter.isRest) { signatureOutput += "..."; } signatureOutput += parameter.name; if (parameter.name === "this") { signatureOutput += "_"; } var parameterType = parameter.type; if (parameterType) { signatureOutput += ":"; signatureOutput += this.getNameToEmit(parameterType, scope); } if (parameter.value) { signatureOutput += " = "; signatureOutput += parameter.value; } } } signatureOutput += ")"; return signatureOutput; }; default_1.prototype.getConstructorMethod = function (as3Class) { var constructorMethod = as3Class.constructorMethod; if (constructorMethod) { return constructorMethod; } var superClass = as3Class.superClass; if (superClass) { return this.getConstructorMethod(superClass); } return null; }; return default_1; }()); exports.default = default_1;