Search in sources :

Example 1 with Builder

use of com.google.javascript.jscomp.JsMessage.Builder in project closure-compiler by google.

the class JsMessageVisitor method visit.

@Override
public void visit(NodeTraversal traversal, Node node, Node parent) {
    String messageKey;
    String originalMessageKey;
    boolean isVar;
    Node msgNode;
    switch(node.getToken()) {
        case NAME:
            // var MSG_HELLO = 'Message'
            if ((parent != null) && (NodeUtil.isNameDeclaration(parent))) {
                messageKey = node.getString();
                originalMessageKey = node.getOriginalName();
                isVar = true;
            } else {
                return;
            }
            msgNode = node.getFirstChild();
            break;
        case ASSIGN:
            // somenamespace.someclass.MSG_HELLO = 'Message'
            isVar = false;
            Node getProp = node.getFirstChild();
            if (!getProp.isGetProp()) {
                return;
            }
            Node propNode = getProp.getLastChild();
            messageKey = propNode.getString();
            originalMessageKey = getProp.getOriginalName();
            msgNode = node.getLastChild();
            break;
        case STRING_KEY:
            if (node.isQuotedString() || !node.hasChildren()) {
                return;
            }
            isVar = false;
            messageKey = node.getString();
            originalMessageKey = node.getOriginalName();
            msgNode = node.getFirstChild();
            break;
        case CALL:
            // goog.getMsg()
            if (node.getFirstChild().matchesQualifiedName(MSG_FUNCTION_NAME)) {
                googMsgNodes.add(node);
            } else if (node.getFirstChild().matchesQualifiedName(MSG_FALLBACK_FUNCTION_NAME)) {
                visitFallbackFunctionCall(traversal, node);
            }
            return;
        default:
            return;
    }
    if (originalMessageKey != null) {
        messageKey = originalMessageKey;
    }
    // Is this a message name?
    boolean isNewStyleMessage = msgNode != null && msgNode.isCall();
    if (!isMessageName(messageKey, isNewStyleMessage)) {
        return;
    }
    if (msgNode == null) {
        compiler.report(traversal.makeError(node, MESSAGE_HAS_NO_VALUE, messageKey));
        return;
    }
    if (msgNode.isGetProp() && msgNode.isQualifiedName() && msgNode.getLastChild().getString().equals(messageKey)) {
        // message will have already been extracted from the base class.
        return;
    }
    // (e.g. "a.b.MSG_X") doesn't use goog.getMsg().
    if (isNewStyleMessage) {
        googMsgNodes.remove(msgNode);
    } else if (style != JsMessage.Style.LEGACY) {
        // TODO(johnlenz): promote this to an error once existing conflicts have been
        // cleaned up.
        compiler.report(traversal.makeError(node, MESSAGE_NOT_INITIALIZED_USING_NEW_SYNTAX));
        if (style == JsMessage.Style.CLOSURE) {
            // Don't extract the message if we aren't accepting LEGACY messages
            return;
        }
    }
    boolean isUnnamedMsg = isUnnamedMessageName(messageKey);
    Builder builder = new Builder(isUnnamedMsg ? null : messageKey);
    OriginalMapping mapping = compiler.getSourceMapping(traversal.getSourceName(), traversal.getLineNumber(), traversal.getCharno());
    if (mapping != null) {
        builder.setSourceName(mapping.getOriginalFile());
    } else {
        builder.setSourceName(traversal.getSourceName());
    }
    try {
        if (isVar) {
            extractMessageFromVariable(builder, node, parent, parent.getParent());
        } else {
            extractMessageFrom(builder, msgNode, node);
        }
    } catch (MalformedException ex) {
        compiler.report(traversal.makeError(ex.getNode(), MESSAGE_TREE_MALFORMED, ex.getMessage()));
        return;
    }
    JsMessage extractedMessage = builder.build(idGenerator);
    // If asked to check named internal messages.
    if (needToCheckDuplications && !isUnnamedMsg && !extractedMessage.isExternal()) {
        checkIfMessageDuplicated(messageKey, msgNode);
    }
    trackMessage(traversal, extractedMessage, messageKey, msgNode, isUnnamedMsg);
    if (extractedMessage.isEmpty()) {
        // value of the message is an empty string. Translators do not like it.
        compiler.report(traversal.makeError(node, MESSAGE_HAS_NO_TEXT, messageKey));
    }
    // New-style messages must have descriptions. We don't emit a warning
    // for legacy-style messages, because there are thousands of
    // them in legacy code that are not worth the effort to fix, since they've
    // already been translated anyway.
    String desc = extractedMessage.getDesc();
    if (isNewStyleMessage && (desc == null || desc.trim().isEmpty()) && !extractedMessage.isExternal()) {
        compiler.report(traversal.makeError(node, MESSAGE_HAS_NO_DESCRIPTION, messageKey));
    }
    JsMessageDefinition msgDefinition = new JsMessageDefinition(msgNode);
    processJsMessage(extractedMessage, msgDefinition);
}
Also used : OriginalMapping(com.google.debugging.sourcemap.proto.Mapping.OriginalMapping) Node(com.google.javascript.rhino.Node) Builder(com.google.javascript.jscomp.JsMessage.Builder)

Aggregations

OriginalMapping (com.google.debugging.sourcemap.proto.Mapping.OriginalMapping)1 Builder (com.google.javascript.jscomp.JsMessage.Builder)1 Node (com.google.javascript.rhino.Node)1