Skip to content
This repository was archived by the owner on Feb 26, 2024. It is now read-only.

Commit 28cc752

Browse files
committed
Skip provided inner classes in processUnprovidedTypes()
1 parent 729641b commit 28cc752

File tree

5 files changed

+130
-2
lines changed

5 files changed

+130
-2
lines changed

src/main/java/com/google/javascript/clutz/DeclarationGenerator.java

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -724,8 +724,7 @@ private void processUnprovidedTypes(Set<String> provides, Set<String> transitive
724724
}
725725

726726
// skip provided symbols (as default or in an namespace).
727-
if (provides.contains(name)
728-
|| (!transitiveProvides.contains(name) && provides.contains(namespace))) {
727+
if (isProvidedSymbol(provides, transitiveProvides, name)) {
729728
continue;
730729
}
731730

@@ -764,6 +763,35 @@ private void processUnprovidedTypes(Set<String> provides, Set<String> transitive
764763
}
765764
}
766765

766+
/** Returns true if the symbol is already provided as default or in a namespace. */
767+
private boolean isProvidedSymbol(
768+
Set<String> provides, Set<String> transitiveProvides, String name) {
769+
if (provides.contains(name)) {
770+
return true;
771+
}
772+
if (transitiveProvides.contains(name)) {
773+
return false;
774+
}
775+
String namespace = getNamespace(name);
776+
Boolean innerClass = false;
777+
while (!namespace.isEmpty()) {
778+
final TypedVar symbol = this.compiler.getTopScope().getOwnSlot(namespace);
779+
if (symbol == null) {
780+
return false;
781+
}
782+
// inner class-like of default export is emitted recursively
783+
if (provides.contains(namespace) && (!innerClass || isDefaultExport(symbol))) {
784+
return true;
785+
}
786+
if (!isClassLike(symbol.getType())) {
787+
return false;
788+
}
789+
namespace = getNamespace(namespace);
790+
innerClass = true;
791+
}
792+
return false;
793+
}
794+
767795
/**
768796
* If any inputs declare a legacy namespace, emit aliases for their exports in goog.module style.
769797
*/
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
declare namespace ಠ_ಠ.clutz {
2+
class module$exports$ns$DoubleInnerClassWithRef {
3+
private noStructuralTyping_module$exports$ns$DoubleInnerClassWithRef : any;
4+
}
5+
}
6+
declare namespace ಠ_ಠ.clutz.module$exports$ns$DoubleInnerClassWithRef {
7+
interface Inner {
8+
baz (e1 : ಠ_ಠ.clutz.module$exports$ns$DoubleInnerClassWithRef.Inner.Enum1 , e2 : ಠ_ಠ.clutz.module$exports$ns$DoubleInnerClassWithRef.Inner.Enum2 ) : void ;
9+
}
10+
}
11+
declare namespace ಠ_ಠ.clutz.module$exports$ns$DoubleInnerClassWithRef.Inner {
12+
enum Enum1 {
13+
FOO = 'foo' ,
14+
}
15+
enum Enum2 {
16+
BAR = 'bar' ,
17+
}
18+
}
19+
declare module 'goog:ns.DoubleInnerClassWithRef' {
20+
import DoubleInnerClassWithRef = ಠ_ಠ.clutz.module$exports$ns$DoubleInnerClassWithRef;
21+
export default DoubleInnerClassWithRef;
22+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
goog.module('ns.DoubleInnerClassWithRef');
2+
3+
class A {}
4+
5+
/**
6+
* @interface
7+
*/
8+
A.Inner = function() {};
9+
10+
/**
11+
* @enum {string}
12+
*/
13+
A.Inner.Enum1 = {
14+
FOO: 'foo'
15+
};
16+
17+
/**
18+
* @enum {string}
19+
*/
20+
A.Inner.Enum2 = {
21+
BAR: 'bar'
22+
};
23+
24+
/**
25+
* @param {A.Inner.Enum1} e1
26+
* @param {A.Inner.Enum2} e2
27+
*/
28+
A.Inner.prototype.baz = function(e1, e2) {};
29+
30+
exports = A;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
declare namespace ಠ_ಠ.clutz.ns.inner_class_of_private_class {
2+
class FooType_ {
3+
private noStructuralTyping_ns_inner_class_of_private_class_FooType_ : any;
4+
foo (inner : ಠ_ಠ.clutz.ns.inner_class_of_private_class.FooType_.Inner ) : void ;
5+
}
6+
}
7+
declare module 'goog:ns.inner_class_of_private_class' {
8+
import inner_class_of_private_class = ಠ_ಠ.clutz.ns.inner_class_of_private_class;
9+
export = inner_class_of_private_class;
10+
}
11+
declare namespace ಠ_ಠ.clutz.ns.inner_class_of_private_class {
12+
let FooInstance : ಠ_ಠ.clutz.ns.inner_class_of_private_class.FooType_ ;
13+
}
14+
declare module 'goog:ns.inner_class_of_private_class.FooInstance' {
15+
import FooInstance = ಠ_ಠ.clutz.ns.inner_class_of_private_class.FooInstance;
16+
export default FooInstance;
17+
}
18+
declare namespace ಠ_ಠ.clutz.ns.inner_class_of_private_class.FooType_ {
19+
class Inner {
20+
private noStructuralTyping_ns_inner_class_of_private_class_FooType__Inner : any;
21+
}
22+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
goog.provide('ns.inner_class_of_private_class');
2+
goog.provide('ns.inner_class_of_private_class.FooInstance');
3+
4+
//!! This is a generalized code of `goog.debug.Trace`.
5+
//!! https://github.com/google/closure-library/blob/master/closure/goog/debug/tracer.js
6+
7+
/**
8+
* @constructor
9+
* @private
10+
*/
11+
ns.inner_class_of_private_class.FooType_ = function() {};
12+
13+
/**
14+
* @param {!ns.inner_class_of_private_class.FooType_.Inner} inner
15+
*/
16+
ns.inner_class_of_private_class.FooType_.prototype.foo = function(inner) {};
17+
18+
/**
19+
* @constructor
20+
*/
21+
ns.inner_class_of_private_class.FooType_.Inner = function() {};
22+
23+
/**
24+
* @type {!ns.inner_class_of_private_class.FooType_}
25+
*/
26+
ns.inner_class_of_private_class.FooInstance = new ns.inner_class_of_private_class.FooType_();

0 commit comments

Comments
 (0)