@Test public void canUseModuleInternalTypedefsInJsDoc() { CompilerUtil compiler = createCompiler(path("foo.js")); compiler.compile( createSourceFile( path("foo.js"), "/** @typedef {{x: number}} */", "var Variable;", "", "/**", " * @param {Variable} a .", " * @param {Variable} b .", " * @return {Variable} .", " */", "exports.add = function(a, b) {", " return {x: a.x + b.x};", "};")); Scope scope = compiler.getCompiler().getTopScope(); Var var = scope.getVar("module$foo"); JSType type = var.getInitialValue().getJSType().toObjectType().getPropertyType("add"); assertTrue(type.isFunctionType()); JSDocInfo info = type.getJSDocInfo(); Node node = info.getTypeNodes().iterator().next(); assertTrue(node.isString()); assertEquals("$jscomp.scope.Variable", node.getString()); assertEquals("Variable", node.getProp(Node.ORIGINALNAME_PROP)); }
@Test public void savesOriginalTypeNameInJsDoc() { CompilerUtil compiler = createCompiler(path("foo.js")); compiler.compile( createSourceFile( path("foo.js"), "/** @constructor */", "var Builder = function(){};", "/** @return {!Builder} . */", "Builder.prototype.returnThis = function() { return this; };", "exports.Builder = Builder")); Scope scope = compiler.getCompiler().getTopScope(); Var var = scope.getVar("module$foo"); JSType type = var.getInitialValue().getJSType().findPropertyType("Builder"); assertTrue(type.isConstructor()); type = type.toObjectType().getTypeOfThis(); assertEquals("$jscomp.scope.Builder", type.toString()); type = type.toObjectType().getPropertyType("returnThis"); assertTrue(type.toString(), type.isFunctionType()); JSDocInfo info = type.getJSDocInfo(); assertNotNull(info); Node node = getOnlyElement(info.getTypeNodes()); assertEquals(Token.BANG, node.getType()); node = node.getFirstChild(); assertTrue(node.isString()); assertEquals("$jscomp.scope.Builder", node.getString()); assertEquals("Builder", node.getProp(Node.ORIGINALNAME_PROP)); }
@Test public void canReferenceConstructorDefinedInTheGlobalScope() { CompilerUtil compiler = createCompiler(path("x/bar.js")); compiler.compile( createSourceFile(path("x/foo.js"), "/** @constructor */", "function Foo() {}"), createSourceFile( path("x/bar.js"), "/** @type {function(new: Foo)} */", "exports.Foo = Foo;")); Scope scope = compiler.getCompiler().getTopScope(); Var var = scope.getVar("module$x$bar"); JSType type = var.getInitialValue().getJSType().findPropertyType("Foo"); assertTrue(type.isConstructor()); type = type.toObjectType().getTypeOfThis(); assertEquals("Foo", type.toString()); }
@Test public void canReferenceConstructorExportedByAnotherModule() { CompilerUtil compiler = createCompiler(path("x/foo.js"), path("x/bar.js")); compiler.compile( createSourceFile(path("x/foo.js"), "/** @constructor */", "exports.Foo = function(){};"), createSourceFile( path("x/bar.js"), "var foo = require('./foo');", "/** @type {function(new: foo.Foo)} */", "exports.Foo = foo.Foo;")); Scope scope = compiler.getCompiler().getTopScope(); Var var = scope.getVar("module$x$bar"); JSType type = var.getInitialValue().getJSType().findPropertyType("Foo"); assertTrue(type.isConstructor()); type = type.toObjectType().getTypeOfThis(); assertEquals("module$x$foo.Foo", type.toString()); }