diff --git a/transpiler/src/main/java/org/jsweet/transpiler/Java2TypeScriptTranslator.java b/transpiler/src/main/java/org/jsweet/transpiler/Java2TypeScriptTranslator.java index fe4fb39e..8126c79e 100644 --- a/transpiler/src/main/java/org/jsweet/transpiler/Java2TypeScriptTranslator.java +++ b/transpiler/src/main/java/org/jsweet/transpiler/Java2TypeScriptTranslator.java @@ -173,7 +173,7 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter { /* Set to true to expose the overloads in the interfaces (will cause issues with abstract classes) */ - private boolean __EXPERIMENTAL_expose = false; + public static boolean __EXPERIMENTAL_expose = true; /** * The name of the field where the parent class is stored in the generated @@ -599,8 +599,10 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter { private PackageSymbol topLevelPackage; public void useModule(ModuleImportDescriptor moduleImport) { - useModule(false, moduleImport.isDirect(), moduleImport.getTargetPackage(), null, moduleImport.getImportedName(), - moduleImport.getPathToImportedClass(), null); + if (moduleImport != null) { + useModule(false, moduleImport.isDirect(), moduleImport.getTargetPackage(), null, + moduleImport.getImportedName(), moduleImport.getPathToImportedClass(), null); + } } private void useModule(boolean require, boolean direct, PackageElement targetPackage, JCTree sourceTree, @@ -2359,12 +2361,14 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter { println().println().printIndent(); printCoreMethodDelegate = false; } - if (__EXPERIMENTAL_expose && isInterfaceMethod(parent, methodDecl) && !methodDecl.sym.isConstructor()) { - printCoreMethodDelegate = true; - visitMethodDef(overload.coreMethod); - println().println().printIndent(); - printCoreMethodDelegate = false; - } + // add overloads in interfaces when the expose option is on +// if (__EXPERIMENTAL_expose && isInterfaceMethod(parent, methodDecl) +// && !methodDecl.sym.isConstructor()) { +// printCoreMethodDelegate = true; +// visitMethodDef(overload.coreMethod); +// println().println().printIndent(); +// printCoreMethodDelegate = false; +// } } else { inCoreWrongOverload = true; if (methodDecl.sym.isDefault() || (!methodDecl.sym.isConstructor() @@ -2392,14 +2396,27 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter { if (addCoreMethod) { visitMethodDef(overload.coreMethod); overload.printed = true; - if (!isInterfaceMethod(parent, methodDecl)) { + if (!isInterfaceMethod(parent, methodDecl) || __EXPERIMENTAL_expose) { println().println().printIndent(); } } if (isInterfaceMethod(parent, methodDecl)) { + // add overloads in interfaces when the expose option is on if (context.options.isGenerateOverloadStubs() && !__EXPERIMENTAL_expose) { return; } +// if (__EXPERIMENTAL_expose) { +// if (methodDecl.sym.owner != parent.sym) { +// for (JCVariableDecl param : methodDecl.params) { +// List typeParameters = methodDecl.getTypeParameters().stream() +// .map(t -> t.type).collect(Collectors.toList()); +// if (param.getType().type instanceof TypeVar +// && !typeParameters.contains(param.getType().type)) { +// return; +// } +// } +// } +// } } } } @@ -2620,6 +2637,19 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter { print(";"); return; } + if (__EXPERIMENTAL_expose && inOverload && isInterfaceMethod(parent, methodDecl)) { + new UsedTypesScanner().scan(methodDecl); + + //MEMORISER TOUTES LES METHODES INJECTES ICI ET LES IMPLEMENTER DANS LES ABSTRACT CLASSES SI ELLES N'EXISTENT PAS!!!!! + +// if (methodDecl.getReturnType().type.tsym instanceof TypeElement && Util.isSourceElement(methodDecl.getReturnType().type.tsym)) { +// if (context.useModules) { +// useModule(getModuleImportDescriptor(methodDecl.getReturnType().type.tsym.getSimpleName().toString(), (TypeElement)methodDecl.getReturnType().type.tsym)); +// } +// } + print(";"); + return; + } if (methodDecl.getBody() == null && !(inCoreWrongOverload && !getScope().declareClassScope) || (methodDecl.mods.getFlags().contains(Modifier.DEFAULT) && !getScope().defaultMethodScope)) { if (!getScope().interfaceScope && methodDecl.getModifiers().getFlags().contains(Modifier.ABSTRACT) @@ -3301,7 +3331,12 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter { StringBuilder sb = new StringBuilder(executable.getSimpleName().toString()); sb.append("$"); for (VariableElement p : executable.getParameters()) { - sb.append(context.modelTypes.erasure(p.asType()).toString().replace('.', '_').replace("[]", "_A")); + if (__EXPERIMENTAL_expose && p.asType().getKind() == TypeKind.TYPEVAR) { + // hack so that the name is compatible with the name exposed in the interface + sb.append("java_lang_Object"); + } else { + sb.append(context.modelTypes.erasure(p.asType()).toString().replace('.', '_').replace("[]", "_A")); + } sb.append("$"); } if (!executable.getParameters().isEmpty()) { @@ -5061,8 +5096,6 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter { name = variablePrefix + (++index); } - System.out.println(" => " + getCurrent()); - int position = stack.size() - 2; while (position >= 0 && !(stack.get(position) instanceof JCMethodDecl)) { if (stack.get(position) instanceof JCBlock) { diff --git a/transpiler/src/main/java/org/jsweet/transpiler/OverloadScanner.java b/transpiler/src/main/java/org/jsweet/transpiler/OverloadScanner.java index c092bd68..4f5d00ef 100644 --- a/transpiler/src/main/java/org/jsweet/transpiler/OverloadScanner.java +++ b/transpiler/src/main/java/org/jsweet/transpiler/OverloadScanner.java @@ -298,60 +298,85 @@ public class OverloadScanner extends AbstractTreeScanner { }); } - private static void safeAdd(Types types, Overload overload, JCMethodDecl method) { - if (!overload.methods.contains(method) && !hasMethodType(types, overload, method)) { - overload.methods.add(method); + private static void safeAdd(Types types, Overload targetOverload, JCMethodDecl method) { + if (method.body == null) { + return; + } + if (!targetOverload.methods.contains(method) && !hasMethodType(types, targetOverload, method)) { + targetOverload.methods.add(method); } } /** * Merges the given overload with another one. */ - public void merge(Types types, Overload otherOverload) { + public void merge(Types types, Overload targetOverload, boolean ignoreOverrides) { // merge default methods for (JCMethodDecl m : methods) { if (m.getModifiers().getFlags().contains(Modifier.DEFAULT)) { boolean overriden = false; - for (JCMethodDecl subm : new ArrayList<>(otherOverload.methods)) { + for (JCMethodDecl subm : new ArrayList<>(targetOverload.methods)) { if (subm.getParameters().size() == m.getParameters().size()) { overriden = true; for (int i = 0; i < subm.getParameters().size(); i++) { - if (!types.isAssignable(m.getParameters().get(i).type, - subm.getParameters().get(i).type)) { + if (!types.isAssignable(types.erasureRecursive(m.getParameters().get(i).type), + types.erasureRecursive(subm.getParameters().get(i).type))) { overriden = false; } } } } if (!overriden) { - safeAdd(types, otherOverload, m); + safeAdd(types, targetOverload, m); } } } // merge other methods - boolean merge = false; - for (JCMethodDecl subm : new ArrayList<>(otherOverload.methods)) { - boolean overrides = false; - for (JCMethodDecl m : new ArrayList<>(methods)) { - if (subm.getParameters().size() == m.getParameters().size()) { - overrides = true; - for (int i = 0; i < subm.getParameters().size(); i++) { - if (!types.isAssignable(m.getParameters().get(i).type, subm.getParameters().get(i).type)) { - overrides = false; + if (ignoreOverrides) { + boolean merge = false; + for (JCMethodDecl subm : new ArrayList<>(targetOverload.methods)) { + boolean overrides = false; + for (JCMethodDecl m : new ArrayList<>(methods)) { + if (subm.getParameters().size() == m.getParameters().size()) { + overrides = true; + for (int i = 0; i < subm.getParameters().size(); i++) { + if (!types.isAssignable(types.erasureRecursive(m.getParameters().get(i).type), + types.erasureRecursive(subm.getParameters().get(i).type))) { + overrides = false; + } } } } + merge = merge || !overrides; } - merge = merge || !overrides; - } - merge = merge || methods.size() > 1; + merge = merge || methods.size() > 1; - if (merge) { + if (merge) { + for (JCMethodDecl m : methods) { + safeAdd(types, targetOverload, m); + } + } + } else { for (JCMethodDecl m : methods) { - safeAdd(types, otherOverload, m); + boolean overriden = false; + for (JCMethodDecl subm : new ArrayList<>(targetOverload.methods)) { + if (subm.getParameters().size() == m.getParameters().size()) { + overriden = true; + for (int i = 0; i < subm.getParameters().size(); i++) { + if (!types.isAssignable(types.erasureRecursive(m.getParameters().get(i).type), + types.erasureRecursive(subm.getParameters().get(i).type))) { + overriden = false; + } + } + } + } + if (!overriden) { + safeAdd(types, targetOverload, m); + } } - } + } + } } @@ -370,11 +395,14 @@ public class OverloadScanner extends AbstractTreeScanner { } Overload superOverload = context.getOverload(clazz, method.sym); if (superOverload != null && superOverload != overload) { - superOverload.merge(types, overload); - if (!context.options.isGenerateOverloadStubs()) { - overload.merge(types, superOverload); + if (!context.options.isGenerateOverloadStubs() || Java2TypeScriptTranslator.__EXPERIMENTAL_expose) { + overload.merge(types, superOverload, true); } + superOverload.merge(types, overload, true); } +// if (Comparable.class.getName().equals(clazz.getQualifiedName().toString()) && superOverload != null && superOverload.methods.size() > 1) { +// System.out.println(); +// } inspectSuperTypes((ClassSymbol) clazz.getSuperclass().tsym, overload, method); for (Type t : clazz.getInterfaces()) { inspectSuperTypes((ClassSymbol) t.tsym, overload, method); @@ -440,7 +468,7 @@ public class OverloadScanner extends AbstractTreeScanner { scan(cu); } // another pass to complete subclasses - if (!context.options.isGenerateOverloadStubs()) { + if (!context.options.isGenerateOverloadStubs() || Java2TypeScriptTranslator.__EXPERIMENTAL_expose) { for (JCCompilationUnit cu : cuList) { scan(cu); } @@ -453,7 +481,7 @@ public class OverloadScanner extends AbstractTreeScanner { } } } - //context.dumpOverloads(System.out); + context.dumpOverloads(System.out); } }