Skip to content

Commit

Permalink
Correctly inherit from descendant TsInterfaces (#75)
Browse files Browse the repository at this point in the history
Fixes #74
  • Loading branch information
vegegoku authored May 3, 2023
1 parent 41877ef commit ffadb6e
Show file tree
Hide file tree
Showing 9 changed files with 219 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public void visit(TypeScriptModule.TsModuleBuilder moduleBuilder) {
.addModifiers(TsModifier.EXPORT)
.addModifiers(getJsModifiers());
new TypeArgumentsVisitor<TsClass.TsClassBuilder>(element.asType(), env).visit(builder);
getSuperClass().ifPresent(builder::superClass);
getSuperClass(element).ifPresent(builder::superClass);
new InterfacesVisitor<TsClass.TsClassBuilder>(element, env).visit(builder);

element.getEnclosedElements().stream()
Expand All @@ -68,22 +68,7 @@ public void visit(TypeScriptModule.TsModuleBuilder moduleBuilder) {
});

TsClass tsClass = builder.build();
getJavaSuperClass()
.ifPresent(
superclass -> {
TsElement superTsElement = TsElement.of(superclass, env);
if (superTsElement.isTsIgnored() || superTsElement.isTsInterface()) {
TsClass.TsClassBuilder superBuilder =
TsClass.builder(superTsElement.getName(), superTsElement.getNamespace());
superTsElement
.element()
.getEnclosedElements()
.forEach(e -> visit(superBuilder, e));
TsClass superTsClass = superBuilder.build();
tsClass.mergeFunctions(superTsClass);
tsClass.mergeProperties(superTsClass);
}
});
getJavaSuperClass().ifPresent(superclass -> processSuperClass(tsClass, superclass));
builder.setEmitProtectedContr(requiresProtectedConstructor());

moduleBuilder.addClass(tsClass);
Expand All @@ -102,6 +87,25 @@ public void visit(TypeScriptModule.TsModuleBuilder moduleBuilder) {
}
}

private void processSuperClass(TsClass tsClass, TypeMirror superclass) {
TsElement superTsElement = TsElement.of(superclass, env);
if (superTsElement.isTsIgnored() || superTsElement.isTsInterface()) {
TsClass.TsClassBuilder superBuilder =
TsClass.builder(superTsElement.getName(), superTsElement.getNamespace());
superTsElement.element().getEnclosedElements().forEach(e -> visit(superBuilder, e));
TsClass superTsClass = superBuilder.build();
tsClass.mergeFunctions(superTsClass);
tsClass.mergeProperties(superTsClass);
} else {
superTsElement
.getJavaSuperClass()
.ifPresent(
typeMirror -> {
processSuperClass(tsClass, typeMirror);
});
}
}

private boolean isSameNameSpaceAsParent(TsElement e) {
if (e.getDeclaredNamespace().isPresent()) {
String childNameSpace = e.getDeclaredNamespace().get();
Expand Down Expand Up @@ -145,7 +149,7 @@ private void visit(TsClass.TsClassBuilder classBuilder, Element enclosedElement)
new ClassMethodVisitor<TsClass.TsClassBuilder>(enclosedElement, env).visit(classBuilder);
}

private Optional<TsClass> getSuperClass() {
private Optional<TsClass> getSuperClass(Element element) {
TypeMirror superclass = ((TypeElement) element).getSuperclass();

if (((TypeElement) env.types().asElement(superclass))
Expand All @@ -165,7 +169,8 @@ private Optional<TsClass> getSuperClass() {
TsClass.builder(superTsElement.getName(), superTsElement.getNamespace());
new TypeArgumentsVisitor<TsClass.TsClassBuilder>(superclass, env).visit(builder);
return Optional.of(builder.build());
} else {
return getSuperClass(superTsElement.element());
}
return Optional.empty();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ public SuperTsInterfaceVisitor(TypeMirror typeMirror, HasProcessorEnv env) {
public void visit(IsClassBuilder<T> builder) {
if (isTsInterface()) {
addInterface(builder, type);
} else {
getJavaSuperClass()
.ifPresent(
typeMirror -> {
new SuperTsInterfaceVisitor<T>(typeMirror, env).visit(builder);
});
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright © 2023 Vertispan
*
* 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.
*/
package com.vertispan.tsdefs.inheritance;

import jsinterop.annotations.JsType;

@JsType
public class JsTypeGrandChild extends NonJsTypeParent {

public String propertyFromA;

public String doSomethingFromA() {
return "";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright © 2023 Vertispan
*
* 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.
*/
package com.vertispan.tsdefs.inheritance;

import jsinterop.annotations.JsType;

@JsType
public class JsTypeGrandChild2 extends NonJsTypeParent2 {

public String propertyFromA;

public String doSomethingFromA() {
return "";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright © 2023 Vertispan
*
* 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.
*/
package com.vertispan.tsdefs.inheritance;

import jsinterop.annotations.JsType;

@JsType
public class JsTypeGrandParent {
public String propertyFromC;

public String doSomethingFromC() {
return "";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright © 2023 Vertispan
*
* 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.
*/
package com.vertispan.tsdefs.inheritance;

public class NonJsTypeParent extends TsInterfaceParent {

public String propertyFromB;

public String doSomethingFromB() {
return "";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright © 2023 Vertispan
*
* 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.
*/
package com.vertispan.tsdefs.inheritance;

public class NonJsTypeParent2 extends JsTypeGrandParent {

public String propertyFromB;

public String doSomethingFromB() {
return "";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright © 2023 Vertispan
*
* 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.
*/
package com.vertispan.tsdefs.inheritance;

import com.vertispan.tsdefs.annotations.TsInterface;
import jsinterop.annotations.JsType;

@TsInterface
@JsType
public class TsInterfaceParent {
public String propertyFromC;

public String doSomethingFromC() {
return "";
}
}
27 changes: 27 additions & 0 deletions jsinterop-ts-defs-processor/src/test/resources/types/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ import TsInterfaceWithJsNullableFields = com.vertispan.tsdefs.jsnullable.TsInter

import UnionTypeApi = com.vertispan.tsdefs.tsunion.UnionTypeApi;

// ---------------- Inheritance ----------------

import JsTypeGrandChild = com.vertispan.tsdefs.inheritance.JsTypeGrandChild;
import JsTypeGrandChild2 = com.vertispan.tsdefs.inheritance.JsTypeGrandChild2;

// ---------- Properties tests -------------------------
const jsTypeWithProperties = new JsTypeWithProperties();

Expand Down Expand Up @@ -531,6 +536,28 @@ jsTypeExtendsTsIgnoredSuperType.childProperty;
jsTypeExtendsTsIgnoredSuperType.property;
jsTypeExtendsTsIgnoredSuperType.doSomething();

const jsTypeGrandChild = new JsTypeGrandChild();

jsTypeGrandChild.propertyFromA;
jsTypeGrandChild.doSomethingFromA();
jsTypeGrandChild.propertyFromC;
jsTypeGrandChild.doSomethingFromC();
// @ts-expect-error
jsTypeGrandChild.propertyFromB;
// @ts-expect-error
jsTypeGrandChild.doSomethingFromB;

const jsTypeGrandChild2 = new JsTypeGrandChild2();

jsTypeGrandChild2.propertyFromA;
jsTypeGrandChild2.doSomethingFromA();
jsTypeGrandChild2.propertyFromC;
jsTypeGrandChild2.doSomethingFromC();
// @ts-expect-error
jsTypeGrandChild2.propertyFromB;
// @ts-expect-error
jsTypeGrandChild2.doSomethingFromB;

// ------------------------ TsName ---------------------

class ImplementsJsInterfaceWithTsName implements JsInterfaceByTsName {
Expand Down

0 comments on commit ffadb6e

Please sign in to comment.