Skip to content

Commit

Permalink
support for regular modules (top-level exports) in declaration files,…
Browse files Browse the repository at this point in the history
… added 'outputKind' mandatory parameter
  • Loading branch information
vojtechhabarta committed Mar 16, 2016
1 parent 05d896f commit b641fd2
Show file tree
Hide file tree
Showing 13 changed files with 132 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ public class Settings {
public String newline = String.format("%n");
public String quotes = "\"";
public String indentString = " ";
public TypeScriptFormat outputFileType = TypeScriptFormat.declarationFile;
public JsonLibrary jsonLibrary = null;
public String namespace = null;
public TypeScriptFileType outputFileType = TypeScriptFileType.declarationFile;
public TypeScriptOutputKind outputKind = null;
public String module = null;
public String namespace = null;
public JsonLibrary jsonLibrary = null;
public List<String> excludedClassNames = null;
public boolean declarePropertiesAsOptional = false;
public String removeTypeNamePrefix = null;
Expand Down Expand Up @@ -55,31 +56,43 @@ public void loadOptionalAnnotations(ClassLoader classLoader, List<String> option
}

public void validate() {
if (outputKind == null) {
throw new RuntimeException("Required 'outputKind' parameter is not configured. " + seeLink());
}
if (outputKind == TypeScriptOutputKind.ambientModule && module == null) {
throw new RuntimeException("'module' parameter must be specified for ambient module. " + seeLink());
}
if (outputKind != TypeScriptOutputKind.ambientModule && module != null) {
throw new RuntimeException("'module' parameter is only applicable to ambient modules. " + seeLink());
}
if (outputKind == TypeScriptOutputKind.ambientModule && outputFileType == TypeScriptFileType.implementationFile) {
throw new RuntimeException("Ambient modules are not supported in implementation files. " + seeLink());
}
if (jsonLibrary == null) {
throw new RuntimeException("Required 'jsonLibrary' is not configured.");
throw new RuntimeException("Required 'jsonLibrary' parameter is not configured.");
}
if (outputFileType != TypeScriptFormat.implementationFile) {
if (outputFileType != TypeScriptFileType.implementationFile) {
for (EmitterExtension emitterExtension : extensions) {
if (emitterExtension.generatesRuntimeCode()) {
throw new RuntimeException(String.format("Extension '%s' generates runtime code but 'outputFileType' is not set to 'implementationFile'.",
throw new RuntimeException(String.format("Extension '%s' generates runtime code but 'outputFileType' parameter is not set to 'implementationFile'.",
emitterExtension.getClass().getSimpleName()));
}
}
}
}

public void validateFileName(File outputFile) {
if (outputFileType == TypeScriptFormat.declarationFile && !outputFile.getName().endsWith(".d.ts")) {
if (outputFileType == TypeScriptFileType.declarationFile && !outputFile.getName().endsWith(".d.ts")) {
throw new RuntimeException("Declaration file must have 'd.ts' extension: " + outputFile);
}
if (outputFileType == TypeScriptFormat.implementationFile && (!outputFile.getName().endsWith(".ts") || outputFile.getName().endsWith(".d.ts"))) {
if (outputFileType == TypeScriptFileType.implementationFile && (!outputFile.getName().endsWith(".ts") || outputFile.getName().endsWith(".d.ts"))) {
throw new RuntimeException("Implementation file must have 'ts' extension: " + outputFile);
}
if (outputFileType == TypeScriptFormat.implementationFile && module != null && !outputFile.getName().equals(module + ".ts")) {
throw new RuntimeException(String.format("Implementation file must be named '%s' when module name is '%s'.", module + ".ts", module));
}
}

private String seeLink() {
return "For more information see 'http://vojtechhabarta.github.io/typescript-generator/doc/ModulesAndNamespaces.html'.";
}

private static <T> List<Class<? extends T>> loadClasses(ClassLoader classLoader, List<String> classNames, Class<T> requiredClassType) {
if (classNames == null) {
Expand All @@ -88,6 +101,7 @@ private static <T> List<Class<? extends T>> loadClasses(ClassLoader classLoader,
try {
final List<Class<? extends T>> classes = new ArrayList<>();
for (String className : classNames) {
System.out.println("Loading class " + className);
final Class<?> loadedClass = classLoader.loadClass(className);
if (requiredClassType.isAssignableFrom(loadedClass)) {
@SuppressWarnings("unchecked")
Expand Down Expand Up @@ -116,6 +130,7 @@ private static <T> List<T> loadInstances(ClassLoader classLoader, List<String> c

private static <T> T loadInstance(ClassLoader classLoader, String className, Class<T> requiredType) {
try {
System.out.println("Loading class " + className);
return requiredType.cast(classLoader.loadClass(className).newInstance());
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
package cz.habarta.typescript.generator;


public enum TypeScriptFormat {
public enum TypeScriptFileType {

declarationFile, implementationFile

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

package cz.habarta.typescript.generator;


public enum TypeScriptOutputKind {

global, module, ambientModule

}
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ private void emitFileComment() {
}

private void emitModule(TsModel model) {
if (settings.module != null && settings.outputFileType == TypeScriptFormat.declarationFile) {
if (settings.outputKind == TypeScriptOutputKind.ambientModule) {
writeNewLine();
writeIndentedLine("declare module \"" + settings.module + "\" {");
writeIndentedLine("declare module " + settings.quotes + settings.module + settings.quotes + " {");
indent++;
emitNamespace(model);
indent--;
Expand All @@ -56,18 +56,22 @@ private void emitModule(TsModel model) {
private void emitNamespace(TsModel model) {
if (settings.namespace != null) {
writeNewLine();
final String prefix = settings.outputFileType == TypeScriptFormat.declarationFile
? (settings.module != null ? "" : "declare ")
: (settings.module != null ? "export " : "");
String prefix = "";
if (settings.outputFileType == TypeScriptFileType.declarationFile && settings.outputKind == TypeScriptOutputKind.global) {
prefix = "declare ";
}
if (settings.outputKind == TypeScriptOutputKind.module) {
prefix = "export ";
}
writeIndentedLine(prefix + "namespace " + settings.namespace + " {");
indent++;
final boolean exportElements = settings.outputFileType == TypeScriptFormat.implementationFile;
final boolean exportElements = settings.outputFileType == TypeScriptFileType.implementationFile;
emitElements(model, exportElements);
indent--;
writeNewLine();
writeIndentedLine("}");
} else {
final boolean exportElements = settings.module != null && settings.outputFileType == TypeScriptFormat.implementationFile;
final boolean exportElements = settings.outputKind == TypeScriptOutputKind.module;
emitElements(model, exportElements);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@ public B getX() {

@Test
public void testCustomOptional() throws Exception {
final Settings settings = new Settings();
settings.jsonLibrary = JsonLibrary.jackson2;
final Settings settings = TestUtils.settings();
settings.mapDate = DateMapping.asString;
settings.customTypeProcessor = new TypeProcessor() {
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ public void testDateAsString() {
}

private static Settings settings(DateMapping mapDate, String namespace) {
final Settings settings = new Settings();
settings.jsonLibrary = JsonLibrary.jackson2;
final Settings settings = TestUtils.settings();
settings.namespace = namespace;
settings.mapDate = mapDate;
return settings;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,31 @@ public class ModulesAndNamespacesTest {

@Test
public void testNamespacesAndModules() {
final File withoutModuleDir = new File("target/test-ts-withoutmodule");
final File withModuleDir = new File("target/test-ts-withmodule");
withoutModuleDir.mkdirs();
withModuleDir.mkdirs();

file("Test1", null, null, TypeScriptFormat.declarationFile, new File(withoutModuleDir, "test-mn1.d.ts"));
file("Test2", null, "NS2", TypeScriptFormat.declarationFile, new File(withoutModuleDir, "test-mn2.d.ts"));
file("Test3", "mod3", null, TypeScriptFormat.declarationFile, new File(withModuleDir, "test-mn3.d.ts"));
file("Test4", "mod4", "NS4", TypeScriptFormat.declarationFile, new File(withModuleDir, "test-mn4.d.ts"));

file("Test5", null, null, TypeScriptFormat.implementationFile, new File(withoutModuleDir, "test-mn5.ts"));
file("Test6", null, "NS6", TypeScriptFormat.implementationFile, new File(withoutModuleDir, "test-mn6.ts"));
file("Test7", "mod7", null, TypeScriptFormat.implementationFile, new File(withModuleDir, "test-mn7.ts"));
file("Test8", "mod8", "NS8", TypeScriptFormat.implementationFile, new File(withModuleDir, "test-mn8.ts"));
final File outputDir = new File("target/test-ts-modules");
outputDir.mkdirs();

file("Test1", null, null, TypeScriptOutputKind.global, TypeScriptFileType.declarationFile, new File(outputDir, "test-mn1.d.ts"));
file("Test2", null, "NS2", TypeScriptOutputKind.global, TypeScriptFileType.declarationFile, new File(outputDir, "test-mn2.d.ts"));
file("Test3a", "mod3a", null, TypeScriptOutputKind.ambientModule, TypeScriptFileType.declarationFile, new File(outputDir, "test-mn3a.d.ts"));
file("Test3b", null, null, TypeScriptOutputKind.module, TypeScriptFileType.declarationFile, new File(outputDir, "test-mn3b.d.ts"));
file("Test4a", "mod4a", "NS4a", TypeScriptOutputKind.ambientModule, TypeScriptFileType.declarationFile, new File(outputDir, "test-mn4a.d.ts"));
file("Test4b", null, "NS4b", TypeScriptOutputKind.module, TypeScriptFileType.declarationFile, new File(outputDir, "test-mn4b.d.ts"));

file("Test5", null, null, TypeScriptOutputKind.global, TypeScriptFileType.implementationFile, new File(outputDir, "test-mn5.ts"));
file("Test6", null, "NS6", TypeScriptOutputKind.global, TypeScriptFileType.implementationFile, new File(outputDir, "test-mn6.ts"));
file("Test7", null, null, TypeScriptOutputKind.module, TypeScriptFileType.implementationFile, new File(outputDir, "test-mn7.ts"));
file("Test8", null, "NS8", TypeScriptOutputKind.module, TypeScriptFileType.implementationFile, new File(outputDir, "test-mn8.ts"));
}

private static void file(String prefix, String module, String namespace, TypeScriptFormat outputFileType, File output) {
private static void file(String prefix, String module, String namespace, TypeScriptOutputKind outputKind, TypeScriptFileType outputFileType, File output) {
final Settings settings = new Settings();
settings.jsonLibrary = JsonLibrary.jackson2;
settings.addTypeNamePrefix = prefix;
settings.module = module;
settings.namespace = namespace;
settings.outputKind = outputKind;
settings.outputFileType = outputFileType;
if (outputFileType == TypeScriptFormat.implementationFile) {
if (outputFileType == TypeScriptFileType.implementationFile) {
settings.extensions.add(new TestFunctionExtention());
}
new TypeScriptGenerator(settings).generateTypeScript(Input.from(Data.class), Output.to(output));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ private TestUtils() {

public static Settings settings() {
final Settings settings = new Settings();
settings.outputKind = TypeScriptOutputKind.global;
settings.jsonLibrary = JsonLibrary.jackson2;
settings.noFileComment = true;
settings.newline = "\n";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public void writeIndentedLine(String line) {
lines.add(line);
}
};
final Settings settings = new Settings();
final Settings settings = TestUtils.settings();
final TypeProcessor typeProcessor = new DefaultTypeProcessor();
final Model model = new Jackson2Parser(settings, typeProcessor).parseModel(Point.class);
final TsModel tsModel = new ModelCompiler(settings, typeProcessor).javaToTypeScript(model);
Expand All @@ -34,10 +34,8 @@ public void writeIndentedLine(String line) {

@Test
public void testInTypeScriptGenerator() {
final Settings settings = new Settings();
settings.newline = "\n";
settings.outputFileType = TypeScriptFormat.implementationFile;
settings.jsonLibrary = JsonLibrary.jackson2;
final Settings settings = TestUtils.settings();
settings.outputFileType = TypeScriptFileType.implementationFile;
settings.addTypeNamePrefix = "Json";
settings.extensions.add(new TypeGuardsForJackson2PolymorphismExtension());
final String actual = new TypeScriptGenerator(settings).generateTypeScript(Input.from(Point.class));
Expand Down
19 changes: 13 additions & 6 deletions typescript-generator-core/src/test/ts/module-usage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,31 @@ var a1: Test1Data;

var a2: NS2.Test2Data;

import * as mod3 from "mod3";
var a3: mod3.Test3Data;
import * as mod3a from "mod3a";
var a3a: mod3a.Test3aData;

import * as mod4 from "mod4";
var a4: mod4.NS4.Test4Data;
import * as mod3b from "../../../target/test-ts-modules/test-mn3b";
var a3b: mod3b.Test3bData;

import * as mod4a from "mod4a";
var a4a: mod4a.NS4a.Test4aData;

import * as mod4b from "../../../target/test-ts-modules/test-mn4b";
var a4b: mod4b.NS4b.Test4bData;


// implementation files

var a5: Test5Data;
test();

var a6: NS6.Test6Data;
NS6.test();

import * as mod7 from "../../../target/test-ts-withmodule/test-mn7";
import * as mod7 from "../../../target/test-ts-modules/test-mn7";
var a7: mod7.Test7Data;
mod7.test();

import * as mod8 from "../../../target/test-ts-withmodule/test-mn8";
import * as mod8 from "../../../target/test-ts-modules/test-mn8";
var a8: mod8.NS8.Test8Data;
mod8.NS8.test();
18 changes: 10 additions & 8 deletions typescript-generator-core/src/test/ts/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@
},
"files": [
"module-usage.ts",
"../../../target/test-ts-withoutmodule/test-mn1.d.ts",
"../../../target/test-ts-withoutmodule/test-mn2.d.ts",
"../../../target/test-ts-withmodule/test-mn3.d.ts",
"../../../target/test-ts-withmodule/test-mn4.d.ts",
"../../../target/test-ts-withoutmodule/test-mn5.ts",
"../../../target/test-ts-withoutmodule/test-mn6.ts",
"../../../target/test-ts-withmodule/test-mn7.ts",
"../../../target/test-ts-withmodule/test-mn8.ts"
"../../../target/test-ts-modules/test-mn1.d.ts",
"../../../target/test-ts-modules/test-mn2.d.ts",
"../../../target/test-ts-modules/test-mn3a.d.ts",
"../../../target/test-ts-modules/test-mn3b.d.ts",
"../../../target/test-ts-modules/test-mn4a.d.ts",
"../../../target/test-ts-modules/test-mn4b.d.ts",
"../../../target/test-ts-modules/test-mn5.ts",
"../../../target/test-ts-modules/test-mn6.ts",
"../../../target/test-ts-modules/test-mn7.ts",
"../../../target/test-ts-modules/test-mn8.ts"
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@
public class GenerateTask extends DefaultTask {

public String outputFile;
public TypeScriptFormat outputFileType;
public TypeScriptFileType outputFileType;
public TypeScriptOutputKind outputKind;
public String module;
public String namespace;
public List<String> classes;
public String classesFromJaxrsApplication;
public List<String> excludeClasses;
public JsonLibrary jsonLibrary;
public String namespace;
public String module;
public boolean declarePropertiesAsOptional;
public String removeTypeNamePrefix;
public String removeTypeNameSuffix;
Expand Down Expand Up @@ -63,10 +64,11 @@ public void generate() throws Exception {
if (outputFileType != null) {
settings.outputFileType = outputFileType;
}
settings.outputKind = outputKind;
settings.module = module;
settings.namespace = namespace;
settings.excludedClassNames = excludeClasses;
settings.jsonLibrary = jsonLibrary;
settings.namespace = namespace;
settings.module = module;
settings.declarePropertiesAsOptional = declarePropertiesAsOptional;
settings.removeTypeNamePrefix = removeTypeNamePrefix;
settings.removeTypeNameSuffix = removeTypeNameSuffix;
Expand Down
Loading

0 comments on commit b641fd2

Please sign in to comment.