use of com.google.javascript.rhino.JSDocInfoBuilder in project closure-compiler by google.
the class Es6RewriteClass method visitNonMethodMember.
/**
* Visits class members other than simple methods: Getters, setters, and computed properties.
*/
private void visitNonMethodMember(Node member, ClassDeclarationMetadata metadata) {
if (member.isComputedProp() && member.isStaticMember()) {
cannotConvertYet(member, "Static computed property");
return;
}
if (member.isComputedProp() && !member.getFirstChild().isQualifiedName()) {
cannotConvert(member.getFirstChild(), "Computed property with non-qualified-name key");
return;
}
JSTypeExpression typeExpr = getTypeFromGetterOrSetter(member);
addToDefinePropertiesObject(metadata, member);
Map<String, JSDocInfo> membersToDeclare;
String memberName;
if (member.isComputedProp()) {
checkState(!member.isStaticMember());
membersToDeclare = metadata.prototypeComputedPropsToDeclare;
memberName = member.getFirstChild().getQualifiedName();
} else {
membersToDeclare = member.isStaticMember() ? metadata.classMembersToDeclare : metadata.prototypeMembersToDeclare;
memberName = member.getString();
}
JSDocInfo existingJSDoc = membersToDeclare.get(memberName);
JSTypeExpression existingType = existingJSDoc == null ? null : existingJSDoc.getType();
if (existingType != null && typeExpr != null && !existingType.equals(typeExpr)) {
compiler.report(JSError.make(member, CONFLICTING_GETTER_SETTER_TYPE, memberName));
} else {
JSDocInfoBuilder jsDoc = new JSDocInfoBuilder(false);
if (member.getJSDocInfo() != null && member.getJSDocInfo().isExport()) {
jsDoc.recordExport();
jsDoc.recordVisibility(Visibility.PUBLIC);
}
if (member.getJSDocInfo() != null && member.getJSDocInfo().isOverride()) {
jsDoc.recordOverride();
} else if (typeExpr == null) {
typeExpr = new JSTypeExpression(new Node(Token.QMARK), member.getSourceFileName());
}
if (typeExpr != null) {
jsDoc.recordType(typeExpr.copy());
}
if (member.isStaticMember() && !member.isComputedProp()) {
jsDoc.recordNoCollapse();
}
membersToDeclare.put(memberName, jsDoc.build());
}
}
use of com.google.javascript.rhino.JSDocInfoBuilder in project closure-compiler by google.
the class PolymerClassRewriter method rewritePolymerCall.
/**
* Rewrites a given call to Polymer({}) to a set of declarations and assignments which can be
* understood by the compiler.
*
* @param exprRoot The root expression of the call to Polymer({}).
* @param cls The extracted {@link PolymerClassDefinition} for the Polymer element created by this
* call.
*/
void rewritePolymerCall(Node exprRoot, final PolymerClassDefinition cls, boolean isInGlobalScope) {
Node objLit = checkNotNull(cls.descriptor);
// Add {@code @lends} to the object literal.
JSDocInfoBuilder objLitDoc = new JSDocInfoBuilder(true);
objLitDoc.recordLends(cls.target.getQualifiedName() + ".prototype");
objLit.setJSDocInfo(objLitDoc.build());
addTypesToFunctions(objLit, cls.target.getQualifiedName(), cls.defType);
PolymerPassStaticUtils.switchDollarSignPropsToBrackets(objLit, compiler);
PolymerPassStaticUtils.quoteListenerAndHostAttributeKeys(objLit, compiler);
for (MemberDefinition prop : cls.props) {
if (prop.value.isObjectLit()) {
PolymerPassStaticUtils.switchDollarSignPropsToBrackets(prop.value, compiler);
}
}
// For simplicity add everything into a block, before adding it to the AST.
Node block = IR.block();
JSDocInfoBuilder constructorDoc = this.getConstructorDoc(cls);
// Remove the original constructor JS docs from the objlit.
Node ctorKey = cls.constructor.value.getParent();
if (ctorKey != null) {
ctorKey.removeProp(Node.JSDOC_INFO_PROP);
}
if (cls.target.isGetProp()) {
// foo.bar = Polymer({...});
Node assign = IR.assign(cls.target.cloneTree(), cls.constructor.value.cloneTree());
NodeUtil.markNewScopesChanged(assign, compiler);
assign.setJSDocInfo(constructorDoc.build());
Node exprResult = IR.exprResult(assign);
exprResult.useSourceInfoIfMissingFromForTree(cls.target);
block.addChildToBack(exprResult);
} else {
// var foo = Polymer({...}); OR Polymer({...});
Node var = IR.var(cls.target.cloneTree(), cls.constructor.value.cloneTree());
NodeUtil.markNewScopesChanged(var, compiler);
var.useSourceInfoIfMissingFromForTree(exprRoot);
var.setJSDocInfo(constructorDoc.build());
block.addChildToBack(var);
}
appendPropertiesToBlock(cls, block, cls.target.getQualifiedName() + ".prototype.");
appendBehaviorMembersToBlock(cls, block);
ImmutableList<MemberDefinition> readOnlyProps = parseReadOnlyProperties(cls, block);
ImmutableList<MemberDefinition> attributeReflectedProps = parseAttributeReflectedProperties(cls);
addInterfaceExterns(cls, readOnlyProps, attributeReflectedProps);
removePropertyDocs(objLit, PolymerClassDefinition.DefinitionType.ObjectLiteral);
Node statements = block.removeChildren();
Node parent = exprRoot.getParent();
// global.
if (this.polymerVersion == 1 && !isInGlobalScope && !cls.target.isGetProp()) {
Node scriptNode = NodeUtil.getEnclosingScript(parent);
scriptNode.addChildrenToFront(statements);
compiler.reportChangeToChangeScope(scriptNode);
} else {
Node beforeRoot = exprRoot.getPrevious();
if (beforeRoot == null) {
parent.addChildrenToFront(statements);
} else {
parent.addChildrenAfter(statements, beforeRoot);
}
compiler.reportChangeToEnclosingScope(parent);
}
compiler.reportChangeToEnclosingScope(statements);
// we might need to update the FeatureSet.
if (cls.features != null) {
Node scriptNode = NodeUtil.getEnclosingScript(parent);
FeatureSet oldFeatures = (FeatureSet) scriptNode.getProp(Node.FEATURE_SET);
FeatureSet newFeatures = oldFeatures.union(cls.features);
if (!newFeatures.equals(oldFeatures)) {
scriptNode.putProp(Node.FEATURE_SET, newFeatures);
compiler.reportChangeToChangeScope(scriptNode);
}
}
if (NodeUtil.isNameDeclaration(exprRoot)) {
Node assignExpr = varToAssign(exprRoot);
parent.replaceChild(exprRoot, assignExpr);
compiler.reportChangeToEnclosingScope(assignExpr);
}
// with the class members.
if (polymerVersion > 1 && propertyRenamingEnabled && cls.descriptor != null) {
Node props = NodeUtil.getFirstPropMatchingKey(cls.descriptor, "properties");
if (props != null && props.isObjectLit()) {
addObjectReflectionCall(cls, props);
}
}
}
use of com.google.javascript.rhino.JSDocInfoBuilder in project closure-compiler by google.
the class PolymerClassRewriter method rewritePolymerClassDeclaration.
/**
* Rewrites a class which extends Polymer.Element to a set of declarations and assignments which
* can be understood by the compiler.
*
* @param clazz The class node
* @param cls The extracted {@link PolymerClassDefinition} for the Polymer element created by this
* call.
*/
void rewritePolymerClassDeclaration(Node clazz, final PolymerClassDefinition cls, boolean isInGlobalScope) {
if (cls.descriptor != null) {
addTypesToFunctions(cls.descriptor, cls.target.getQualifiedName(), cls.defType);
}
PolymerPassStaticUtils.switchDollarSignPropsToBrackets(NodeUtil.getClassMembers(clazz), compiler);
for (MemberDefinition prop : cls.props) {
if (prop.value.isObjectLit()) {
PolymerPassStaticUtils.switchDollarSignPropsToBrackets(prop.value, compiler);
}
}
// For simplicity add everything into a block, before adding it to the AST.
Node block = IR.block();
appendPropertiesToBlock(cls, block, cls.target.getQualifiedName() + ".prototype.");
ImmutableList<MemberDefinition> readOnlyProps = parseReadOnlyProperties(cls, block);
ImmutableList<MemberDefinition> attributeReflectedProps = parseAttributeReflectedProperties(cls);
addInterfaceExterns(cls, readOnlyProps, attributeReflectedProps);
// If an external interface is required, mark the class as implementing it
if (!readOnlyProps.isEmpty() || !attributeReflectedProps.isEmpty()) {
JSDocInfoBuilder classInfo = JSDocInfoBuilder.maybeCopyFrom(clazz.getJSDocInfo());
String interfaceName = getInterfaceName(cls);
JSTypeExpression interfaceType = new JSTypeExpression(new Node(Token.BANG, IR.string(interfaceName)), VIRTUAL_FILE);
classInfo.recordImplementedInterface(interfaceType);
clazz.setJSDocInfo(classInfo.build());
}
if (block.hasChildren()) {
removePropertyDocs(cls.descriptor, cls.defType);
Node stmt = NodeUtil.getEnclosingStatement(clazz);
stmt.getParent().addChildrenAfter(block.removeChildren(), stmt);
compiler.reportChangeToEnclosingScope(stmt);
}
addReturnTypeIfMissing(cls, "is", new JSTypeExpression(IR.string("string"), VIRTUAL_FILE));
Node type = new Node(Token.BANG);
Node array = IR.string("Array");
type.addChildToBack(array);
Node arrayTemplateType = new Node(Token.BLOCK, IR.string("string"));
array.addChildToBack(arrayTemplateType);
addReturnTypeIfMissing(cls, "observers", new JSTypeExpression(type, VIRTUAL_FILE));
addReturnTypeIfMissing(cls, "properties", new JSTypeExpression(IR.string(POLYMER_ELEMENT_PROP_CONFIG), VIRTUAL_FILE));
// with the class members.
if (propertyRenamingEnabled && cls.descriptor != null) {
addObjectReflectionCall(cls, cls.descriptor);
}
}
use of com.google.javascript.rhino.JSDocInfoBuilder in project closure-compiler by google.
the class PolymerClassRewriter method addInterfaceExterns.
/**
* Adds an interface for the given ClassDefinition to externs. This allows generated setter
* functions for read-only properties to avoid renaming altogether.
*
* @see https://www.polymer-project.org/0.8/docs/devguide/properties.html#read-only
*/
private void addInterfaceExterns(final PolymerClassDefinition cls, List<MemberDefinition> readOnlyProps, List<MemberDefinition> attributeReflectedProps) {
Node block = IR.block();
String interfaceName = getInterfaceName(cls);
Node fnNode = NodeUtil.emptyFunction();
compiler.reportChangeToChangeScope(fnNode);
Node varNode = IR.var(NodeUtil.newQName(compiler, interfaceName), fnNode);
JSDocInfoBuilder info = new JSDocInfoBuilder(true);
info.recordInterface();
varNode.setJSDocInfo(info.build());
block.addChildToBack(varNode);
if (polymerVersion == 1) {
// For Polymer 1, all declared properties are non-renameable
appendPropertiesToBlock(cls, block, interfaceName + ".prototype.");
} else {
List<MemberDefinition> interfaceProperties = new ArrayList<>();
interfaceProperties.addAll(readOnlyProps);
if (attributeReflectedProps != null) {
interfaceProperties.addAll(attributeReflectedProps);
}
// For Polymer 2, only read-only properties and reflectToAttribute properties are
// non-renameable. Other properties follow the ALL_UNQUOTED renaming rules.
PolymerClassDefinition tmpDef = new PolymerClassDefinition(cls.defType, cls.definition, cls.target, cls.descriptor, null, null, null, interfaceProperties, null, null);
// disallow renaming of readonly properties
appendPropertiesToBlock(tmpDef, block, interfaceName + ".prototype.");
}
for (MemberDefinition prop : readOnlyProps) {
// Add all _set* functions to avoid renaming.
String propName = prop.name.getString();
String setterName = "_set" + propName.substring(0, 1).toUpperCase() + propName.substring(1);
Node setterExprNode = IR.exprResult(NodeUtil.newQName(compiler, interfaceName + ".prototype." + setterName));
JSDocInfoBuilder setterInfo = new JSDocInfoBuilder(true);
JSTypeExpression propType = PolymerPassStaticUtils.getTypeFromProperty(prop, compiler);
setterInfo.recordParameter(propName, propType);
setterExprNode.getFirstChild().setJSDocInfo(setterInfo.build());
block.addChildToBack(setterExprNode);
}
block.useSourceInfoIfMissingFromForTree(polymerElementExterns);
Node scopeRoot = polymerElementExterns;
if (!scopeRoot.isScript()) {
scopeRoot = scopeRoot.getParent();
}
Node stmts = block.removeChildren();
scopeRoot.addChildrenToBack(stmts);
compiler.reportChangeToEnclosingScope(stmts);
}
use of com.google.javascript.rhino.JSDocInfoBuilder in project closure-compiler by google.
the class ProcessClosurePrimitives method createUnknownTypeJsDocInfo.
private JSDocInfo createUnknownTypeJsDocInfo() {
JSDocInfoBuilder castToUnknownBuilder = new JSDocInfoBuilder(true);
castToUnknownBuilder.recordType(new JSTypeExpression(JsDocInfoParser.parseTypeString("?"), "<ProcessClosurePrimitives.java>"));
return castToUnknownBuilder.build();
}
Aggregations