com.google.javascript.jscomp.TypedVar Java Examples
The following examples show how to use
com.google.javascript.jscomp.TypedVar.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: DeclarationGenerator.java From clutz with MIT License | 6 votes |
/** * Finds all typedefs in the program and build a Type -> typedef name mapping. The mapping is * needed because when walking type definitions closure inlines the typedefs values. */ void collectTypedefs() { for (TypedVar var : compiler.getTopScope().getAllSymbols()) { // In Closure, unlike TypeScript there is no pure type space. Thus even typedefs declare // symbols. The type of the symbol corresponding to the typedef is *not* the same as the type // declared by the typedef. JSType type = var.getType(); if (type == null || !isTypedef(type) || var.getName().startsWith("window.") || isPrivate(var.getJSDocInfo())) { continue; } JSType realType = compiler.getTypeRegistry().getGlobalType(var.getName()); if (realType != null && shouldEmitTypedefByName(realType) && !typedefs.containsKey(realType) && !PlatformSymbols.TYPESCRIPT_LIB_D_TS.contains(var.getName()) && !PlatformSymbols.CLOSURE_EXTERNS_NOT_USED_IN_TYPESCRIPT.contains(var.getName())) { typedefs.put(realType, var.getName()); } } }
Example #2
Source File: NodeModulePassTest.java From js-dossier with Apache License 2.0 | 6 votes |
@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;")); TypedScope scope = compiler.getCompiler().getTopScope(); TypedVar var = scope.getVar("module$exports$module$x$bar"); JSType type = var.getInitialValue().getJSType().findPropertyType("Foo"); assertTrue(type.isConstructor()); type = type.toObjectType().getTypeOfThis(); assertEquals("Foo", type.toString()); }
Example #3
Source File: NodeModulePassTest.java From js-dossier with Apache License 2.0 | 6 votes |
@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;")); TypedScope scope = compiler.getCompiler().getTopScope(); TypedVar var = scope.getVar("module$exports$module$x$bar"); JSType type = var.getInitialValue().getJSType().findPropertyType("Foo"); assertTrue(type.isConstructor()); type = type.toObjectType().getTypeOfThis(); assertEquals("module$exports$module$x$foo.Foo", type.toString()); }
Example #4
Source File: DeclarationGenerator.java From clutz with MIT License | 6 votes |
private boolean needsAlias(Set<String> shadowedSymbols, String provide, TypedVar symbol) { if (!shadowedSymbols.contains(provide)) { return false; } // Emit var foo : any for provided but not declared symbols. if (symbol == null) { return true; } JSType type = symbol.getType(); if (type == null) { return false; } // Emit var foo : PrivateType for private symbols. if (isPrivate(type.getJSDocInfo()) && !isConstructor(type.getJSDocInfo())) { return true; } // Only var declarations have collisions, while class, interface, function, and typedef can // coexist with namespaces. if (type.isInterface() || type.isConstructor() || type.isFunctionType() || isTypedef(type)) { return false; } return isDefaultExport(symbol); }
Example #5
Source File: NodeModulePassTest.java From js-dossier with Apache License 2.0 | 5 votes |
@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};", "};")); TypedScope scope = compiler.getCompiler().getTopScope(); TypedVar var = scope.getVar("module$exports$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("module$contents$module$foo_Variable", node.getString()); assertEquals("Variable", node.getProp(Node.ORIGINALNAME_PROP)); }
Example #6
Source File: DeclarationGenerator.java From clutz with MIT License | 5 votes |
/** * Precompute the list of children symbols for all top-scope symbols. * * <p>I.e. For each x.y -> [x.y.z, x.y.w] */ void precomputeChildLists() { for (TypedVar var : compiler.getTopScope().getAllSymbols()) { String namespace = getNamespace(var.getName()); if (!namespace.equals("")) { childListMap.put(namespace, var); } } }
Example #7
Source File: DeclarationGenerator.java From clutz with MIT License | 5 votes |
/** * Special emit for emitting namespaces for typedefs as one-offs. Typedefs (type aliases in TS) * are special because their information does not come solely from a TypedVar object, but rather * from a pair of name (string) and type (JSType). * * <p>Note that this only handles default exports of typedefs. Typedefs as properties on an * already exported object (like class) are handled separately. */ private void declareTypedefNamespace(TypedVar typedef, JSType typedefType, Set<String> provides) { String typedefName = typedef.getName(); String namespace = getNamespace(typedefName); emitGeneratedFromFileComment(typedef.getSourceFile()); // Ideally we should be using declareNamespace here, but it cannot handle gluing the TypedVar // symbol with the additional JSType typedefType. emitNamespaceBegin(namespace); new TreeWalker(compiler.getTypeRegistry(), provides, false, false) .visitTypeAlias(typedefType, typedefName, false); emitNamespaceEnd(); }
Example #8
Source File: NodeModulePassTest.java From js-dossier with Apache License 2.0 | 5 votes |
@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")); TypedScope scope = compiler.getCompiler().getTopScope(); TypedVar var = scope.getVar("module$exports$module$foo"); JSType type = var.getInitialValue().getJSType().findPropertyType("Builder"); assertTrue(type.isConstructor()); type = type.toObjectType().getTypeOfThis(); assertEquals("module$exports$module$foo.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.getToken()); node = node.getFirstChild(); assertTrue(node.isString()); assertEquals("module$exports$module$foo.Builder", node.getString()); assertEquals("Builder", node.getProp(Node.ORIGINALNAME_PROP)); }
Example #9
Source File: DeclarationGenerator.java From clutz with MIT License | 5 votes |
/** * If any inputs declare a legacy namespace, emit aliases for their exports in goog.module style. */ private void declareLegacyNamespaceAliases() { if (!legacyNamespaceReexportMap.isEmpty()) { for (Entry<String, String> e : legacyNamespaceReexportMap.entrySet()) { String namespace; String googModuleStyleName; if (e.getKey().contains(".")) { List<String> nameParts = DOT_SPLITTER.splitToList(e.getKey()); namespace = nameParts.get(0); googModuleStyleName = nameParts.get(1); } else { namespace = ""; googModuleStyleName = e.getKey(); } TreeWalker treeWalker = new TreeWalker(compiler.getTypeRegistry(), new LinkedHashSet<>(), false, false); TypedVar symbol = compiler.getTopScope().getOwnSlot(e.getValue()); if (symbol != null) { JSType type = symbol.getType(); if (type != null && isDefiningType(type)) { emitGeneratedFromFileComment(symbol.getSourceFile()); emitNamespaceBegin(namespace); treeWalker.visitTypeValueAlias(googModuleStyleName, type.toMaybeObjectType()); emitNamespaceEnd(); } } } } }
Example #10
Source File: DeclarationGenerator.java From clutz with MIT License | 5 votes |
private boolean isAliasedClassOrInterface(TypedVar symbol, JSType type) { // Confusingly typedefs are constructors. However, they cannot be aliased AFAICT. if (type.isNoType()) return false; if (!type.isConstructor() && !type.isInterface()) return false; String symbolName = symbol.getName(); String typeName = type.getDisplayName(); // Turns out that for aliases the symbol and type name differ. return !symbolName.equals(typeName) || KNOWN_CLASS_ALIASES.containsKey(symbolName); }
Example #11
Source File: AbstractClosureVisitor.java From jsinterop-generator with Apache License 2.0 | 5 votes |
public void accept(TypedScope scope) { pushCurrentJavaType(scope.getTypeOfThis()); if (visitTopScope(scope)) { for (TypedVar symbol : scope.getVarIterable()) { if (isDefinedInExternFiles(symbol) && isNotNamespaced(symbol)) { accept(symbol, true); } } } popCurrentJavaType(); }
Example #12
Source File: DeclarationGenerator.java From clutz with MIT License | 5 votes |
/** * Extra walk is required for inner classes and inner enums. They are allowed in closure, but not * in TS, so we have to generate a namespace-class pair in TS. In the case of the externs, however * we *do* go through all symbols so this pass is not needed. In the case of aliased classes, we * cannot emit inner classes, due to a var-namespace clash. * * <p>Similarly, for "namespace" types - i.e. @const on an inferred {}, we cannot safely emit * namespace pair. */ private void maybeQueueForInnerWalk( boolean isExtern, Map<String, ObjectType> symbolsToInnerWalk, TypedVar propertySymbol, String propertyName) { ObjectType oType = propertySymbol.getType().toMaybeObjectType(); if (!isExtern && oType != null && !isAliasedClassOrInterface(propertySymbol, oType) && !isNamespaceType(oType)) { symbolsToInnerWalk.put(propertyName, oType); } }
Example #13
Source File: DeclarationGenerator.java From clutz with MIT License | 5 votes |
private boolean isPrototypeMethod(TypedVar other) { if (other.getType() != null && other.getType().isOrdinaryFunction()) { JSType typeOfThis = ((FunctionType) other.getType()).getTypeOfThis(); if (typeOfThis != null && !typeOfThis.isUnknownType()) { return true; } } return false; }
Example #14
Source File: DeclarationGenerator.java From clutz with MIT License | 4 votes |
private void visitTypeAlias(JSType registryType, TypedVar symbol) { visitTypeAlias(registryType, getUnqualifiedName(symbol), false); }
Example #15
Source File: DeclarationGenerator.java From clutz with MIT License | 4 votes |
private static boolean isDefaultExport(TypedVar symbol) { if (symbol.getType() == null) return true; ObjectType otype = symbol.getType().toMaybeObjectType(); if (otype != null && otype.getOwnPropertyNames().size() == 0) return true; return !isNamespaceType(symbol.getType()); }
Example #16
Source File: DeclarationGenerator.java From clutz with MIT License | 4 votes |
private void emitSkipTypeAlias(TypedVar symbol) { emit( "/* skipped emitting type alias " + symbol.getName() + " to avoid collision with existing one in lib.d.ts. */"); }
Example #17
Source File: BuildSymbolTablePassTest.java From js-dossier with Apache License 2.0 | 4 votes |
@Test public void googScope() { Scenario scenario = new Scenario(); SymbolTable table = scenario .addFile( stdInput, "goog.provide('foo.bar.baz');", "goog.scope(function() {", "const fbb = foo.bar.baz;", "fbb.quot = function() {};", "fbb.quot.quux = 123;", "fbb.A = class X {};", "foo.bar.baz.B = class Y {};", "});", "foo.bar.baz.end = 1;") .compile(); assertThat(table) .containsExactly( "foo.bar.baz", "foo.bar.baz.quot", "foo.bar.baz.quot.quux", "foo.bar.baz.A", "foo.bar.baz.B", "foo.bar.baz.end"); // Need to find the node for fbb.quot so we can find the symbol table for the block. TypedScope scope = scenario.getCompiler().getTopScope(); TypedVar var = scope.getVar("foo.bar.baz.quot"); SymbolTable varTable = table.findTableFor(var.getNode()); assertThat(varTable).isNotSameAs(table); assertThat(varTable.getParentScope()).isSameAs(table); assertThat(varTable).containsExactly("fbb", "fbb.quot", "fbb.quot.quux", "fbb.A"); assertThat(varTable).hasOwnSymbol("fbb").that().isAReferenceTo("foo.bar.baz"); assertThat(varTable).hasOwnSymbol("fbb.quot").that().isAReferenceTo("foo.bar.baz.quot"); assertThat(varTable) .hasOwnSymbol("fbb.quot.quux") .that() .isAReferenceTo("foo.bar.baz.quot.quux"); assertThat(varTable).hasOwnSymbol("fbb.A").that().isAReferenceTo("foo.bar.baz.A"); }
Example #18
Source File: DeclarationGenerator.java From clutz with MIT License | 4 votes |
private String getUnqualifiedName(TypedVar symbol) { return getUnqualifiedName(symbol.getName()); }
Example #19
Source File: DeclarationGenerator.java From clutz with MIT License | 4 votes |
private boolean isPrivate(String name) { TypedVar var = compiler.getTopScope().getOwnSlot(name); if (var == null) return false; return isPrivate(var.getJSDocInfo()); }
Example #20
Source File: DeclarationGenerator.java From clutz with MIT License | 4 votes |
private void sortSymbols(List<TypedVar> symbols) { Collections.sort(symbols, BY_SOURCE_FILE_AND_VAR_NAME); }
Example #21
Source File: DeclarationGenerator.java From clutz with MIT License | 4 votes |
/** * Closure does not require all types to be explicitly provided, if they are only used in type * positions. However, our emit phases only emits goog.provided symbols and namespaces, so this * extra pass is required, in order to have valid output. */ private void processUnprovidedTypes(Set<String> provides, Set<String> transitiveProvides) { /** * A new set of types can be discovered while visiting unprovided types. To prevent an infinite * loop in a pathological case, limit to a number of passes. * * <p>TODO(rado): investigate https://github.com/angular/clutz/pull/246 and removing this pass * altogether. */ int maxTypeUsedDepth = 5; Set<String> typesEmitted = new LinkedHashSet<>(); while (maxTypeUsedDepth > 0) { int typesUsedCount = typesUsed.size(); // AFAICT, there is no api for going from type to symbol, so iterate all symbols first. for (TypedVar symbol : compiler.getTopScope().getAllSymbols()) { String name = symbol.getName(); String namespace = getNamespace(name); // skip unused symbols, symbols already emitted or symbols whose namespace is emitted // (unless the symbols have their own provide). if (!typesUsed.contains(name) || typesEmitted.contains(name) || (!transitiveProvides.contains(name) && typesEmitted.contains(namespace))) { continue; } // skip provided symbols (as default or in an namespace). if (provides.contains(name) || (!transitiveProvides.contains(name) && provides.contains(namespace))) { continue; } // skip emit for provided inner symbols too as they are covered by the walkInnerSymbols // pass. if (isInnerSymbol(provides, name)) { continue; } // Skip extern symbols (they have a separate pass) and skip built-ins. // Built-ins can be indentified by having null as input file. CompilerInput symbolInput = this.compiler.getInput(new InputId(symbol.getInputName())); if (symbolInput == null || symbolInput.isExtern()) continue; // Type inference sometimes creates symbols for undeclared qualified names when narrowing // their type in a flow scope. These should not be emitted and can be detected by noticing // the declaration 'node' is not used as an lvalue. Node nameNode = symbol.getNode(); if (!NodeUtil.isLValue(nameNode) && !nameNode.getParent().isExprResult()) { continue; } // A symbol with a name, but a null type is likely a typedef. DeclareNamespace cannot handle // this scenario, but declareTypedefNamespace if (symbol.getType() == null) { JSType typedef = compiler.getTypeRegistry().getGlobalType(name); if (typedef != null) { declareTypedefNamespace(symbol, typedef, Collections.emptySet()); typesEmitted.add(name); } continue; } declareNamespace( namespace, symbol, name, /* isDefault */ true, Collections.<String>emptySet(), /* isExtern */ false); typesEmitted.add(name); } // if no new types seen, safely break out. if (typesUsed.size() == typesUsedCount) break; maxTypeUsedDepth--; } }
Example #22
Source File: DeclarationGenerator.java From clutz with MIT License | 4 votes |
private boolean isArrayLike(TypedVar symbol) { return symbol.getName().endsWith(".ArrayLike"); }
Example #23
Source File: DeclarationGenerator.java From clutz with MIT License | 4 votes |
/** * Reserved words are problematic because they cannot be used as var declarations, but are valid * properties. For example: * * <pre> * var switch = 0; // parses badly in JS. * foo.switch = 0; // ok. * </pre> * * This means that closure code is allowed to goog.provide('ng.components.switch'), which cannot * trivially translate in TS to: * * <pre> * namespace ng.components { * var switch : ...; * } * </pre> * * Instead, go one step higher and generate: * * <pre> * namespace ng { * var components : {switch: ..., }; * } * </pre> * * This turns a namespace into a property of its parent namespace. Note: this violates the * invariant that generated namespaces are 1-1 with getNamespace of goog.provides. */ private void processReservedSymbols(TreeSet<String> provides, TypedScope topScope) { Set<String> collapsedNamespaces = new TreeSet<>(); for (String reservedProvide : provides) { if (RESERVED_JS_WORDS.contains(getUnqualifiedName(reservedProvide))) { TypedVar var = topScope.getOwnSlot(reservedProvide); String namespace = getNamespace(reservedProvide); if (collapsedNamespaces.contains(namespace)) continue; collapsedNamespaces.add(namespace); Set<String> properties = getSubNamespace(provides, namespace); if (var != null) { emitGeneratedFromFileComment(var.getSourceFile()); } emitNamespaceBegin(getNamespace(namespace)); emit("let"); emit(getUnqualifiedName(namespace)); emit(": {"); Iterator<String> bundledIt = properties.iterator(); while (bundledIt.hasNext()) { emit(getUnqualifiedName(bundledIt.next())); emit(":"); if (var != null) { TreeWalker walker = new TreeWalker(compiler.getTypeRegistry(), provides, false, false); walker.visitType(var.getType()); } else { emit("any"); } if (bundledIt.hasNext()) emit(","); } emit("};"); emitBreak(); emitNamespaceEnd(); for (String property : properties) { // Assume that all symbols that are siblings of the reserved word are default exports. declareModule(property, true, property, true, var != null ? var.getSourceFile() : null); } } } // Remove the symbols that we have emitted above. Iterator<String> it = provides.iterator(); while (it.hasNext()) { if (collapsedNamespaces.contains(getNamespace(it.next()))) it.remove(); } }
Example #24
Source File: AbstractClosureVisitor.java From jsinterop-generator with Apache License 2.0 | 4 votes |
private boolean isDefinedInExternFiles(TypedVar symbol) { return externFileNamesSet.contains(symbol.getInputName()); }
Example #25
Source File: AbstractClosureVisitor.java From jsinterop-generator with Apache License 2.0 | 4 votes |
private static boolean isNotNamespaced(TypedVar symbol) { return !symbol.getName().contains("."); }