Search in sources :

Example 1 with OriginalMapping

use of com.google.debugging.sourcemap.proto.Mapping.OriginalMapping in project closure-compiler by google.

the class SourceMap method addMapping.

public void addMapping(Node node, FilePosition outputStartPosition, FilePosition outputEndPosition) {
    // If the node does not have an associated source file or
    // its line number is -1, then the node does not have sufficient
    // information for a mapping to be useful.
    StaticSourceFile sourceFile = node.getStaticSourceFile();
    if (sourceFile == null || node.getLineno() < 0) {
        return;
    }
    String sourceFileName = sourceFile.getName();
    int lineNo = node.getLineno();
    int charNo = node.getCharno();
    String originalName = SourceMap.getOriginalName(node);
    if (mapping != null) {
        OriginalMapping sourceMapping = mapping.getSourceMapping(sourceFileName, lineNo, charNo);
        if (sourceMapping != null) {
            sourceFileName = sourceMapping.getOriginalFile();
            lineNo = sourceMapping.getLineNumber();
            charNo = sourceMapping.getColumnPosition();
            String identifier = sourceMapping.getIdentifier();
            if (sourceMapping.hasIdentifier() && !identifier.isEmpty()) {
                originalName = identifier;
            }
        }
    }
    sourceFileName = fixupSourceLocation(sourceFileName);
    // Rhino source lines are one based but for v3 source maps, we make
    // them zero based.
    int lineBaseOffset = 1;
    generator.addMapping(sourceFileName, originalName, new FilePosition(lineNo - lineBaseOffset, charNo), outputStartPosition, outputEndPosition);
}
Also used : OriginalMapping(com.google.debugging.sourcemap.proto.Mapping.OriginalMapping) StaticSourceFile(com.google.javascript.rhino.StaticSourceFile) FilePosition(com.google.debugging.sourcemap.FilePosition)

Example 2 with OriginalMapping

use of com.google.debugging.sourcemap.proto.Mapping.OriginalMapping in project closure-compiler by google.

the class SourceMapConsumerV3Test method testSourceMappingApproximatedLine.

@Test
public void testSourceMappingApproximatedLine() throws Exception {
    consumer.parse(GSON.toJson(TestJsonBuilder.create().setVersion(3).setMappings(";;;;;;;;;;;;;;;;;;IAAMA,K,GACL,eAAaC,EAAb,EAAiB;AAAA;;AAAA;;AAChB,OAAKA,EAAL,GAAUA,EAAV;AACA,C;;IAEIC,S;;;;;;;AACL,qBAAYD,EAAZ,EAAgB;AAAA;;AAAA,6BACTA,EADS;AAEf;;;EAHsBD,K;;AAKxB,IAAIG,CAAC,GAAG,IAAID,SAAJ,CAAc,UAAd,CAAR").setSourcesContent("class Shape {\n" + "\tconstructor (id) {\n" + "\t\tthis.id = id;\n" + "\t}\n" + "}\n" + "class Rectangle extends Shape {\n" + "\tconstructor(id) {\n" + "\t\tsuper(id);\n" + "\t}\n" + "}\n" + "var s = new Rectangle(\"Shape ID\");").setSources("testcode").setNames("Shape", "id", "Rectangle", "s").build()));
    OriginalMapping mapping = consumer.getMappingForLine(40, 10);
    assertThat(mapping).isNotNull();
    // The Previous line mapping was retrieved, and thus it is "approximated"
    assertThat(mapping.getLineNumber()).isEqualTo(9);
    assertThat(mapping.getPrecision()).isEqualTo(Precision.APPROXIMATE_LINE);
}
Also used : OriginalMapping(com.google.debugging.sourcemap.proto.Mapping.OriginalMapping) Test(org.junit.Test)

Example 3 with OriginalMapping

use of com.google.debugging.sourcemap.proto.Mapping.OriginalMapping in project closure-compiler by google.

the class Compiler method getSourceMapping.

@Override
@Nullable
public OriginalMapping getSourceMapping(String sourceName, int lineNumber, int columnNumber) {
    if (sourceName == null) {
        return null;
    }
    SourceMapInput sourceMap = inputSourceMaps.get(sourceName);
    if (sourceMap == null) {
        return null;
    }
    // JSCompiler uses 1-indexing for lineNumber and 0-indexing for columnNumber.
    // Sourcemaps use 1-indexing for both.
    SourceMapConsumerV3 consumer = sourceMap.getSourceMap(errorManager);
    if (consumer == null) {
        return null;
    }
    OriginalMapping result = consumer.getMappingForLine(lineNumber, columnNumber + 1);
    if (result == null) {
        return null;
    }
    // First check to see if the original file was loaded from an input source map.
    String sourceMapOriginalPath = sourceMap.getOriginalPath();
    String resultOriginalPath = result.getOriginalFile();
    final String relativePath;
    // Resolving the paths to a source file is expensive, so check the cache first.
    if (sourceMapOriginalPath.equals(resolvedSourceMap.originalPath) && resultOriginalPath.equals(resolvedSourceMap.sourceMapPath)) {
        relativePath = resolvedSourceMap.relativePath;
    } else {
        relativePath = resolveSibling(sourceMapOriginalPath, resultOriginalPath);
        SourceFile source = getSourceFileByName(relativePath);
        if (source == null && !isNullOrEmpty(resultOriginalPath)) {
            source = SourceMapResolver.getRelativePath(sourceMap.getOriginalPath(), result.getOriginalFile());
            if (source != null) {
                sourceMapOriginalSources.putIfAbsent(relativePath, source);
            }
        }
        // Cache this resolved source for the next caller.
        resolvedSourceMap.originalPath = sourceMapOriginalPath;
        resolvedSourceMap.sourceMapPath = resultOriginalPath;
        resolvedSourceMap.relativePath = relativePath;
    }
    return result.toBuilder().setOriginalFile(relativePath).setColumnPosition(result.getColumnPosition() - 1).build();
}
Also used : OriginalMapping(com.google.debugging.sourcemap.proto.Mapping.OriginalMapping) SourceMapConsumerV3(com.google.debugging.sourcemap.SourceMapConsumerV3) Nullable(javax.annotation.Nullable)

Example 4 with OriginalMapping

use of com.google.debugging.sourcemap.proto.Mapping.OriginalMapping in project closure-compiler by google.

the class SourceMapConsumerV3 method createReverseMapping.

/**
 * Reverse the source map; the created mapping will allow us to quickly go
 * from a source file and line number to a collection of target
 * OriginalMappings.
 */
private void createReverseMapping() {
    reverseSourceMapping = new HashMap<>();
    for (int targetLine = 0; targetLine < lines.size(); targetLine++) {
        ArrayList<Entry> entries = lines.get(targetLine);
        if (entries != null) {
            for (Entry entry : entries) {
                if (entry.getSourceFileId() != UNMAPPED && entry.getSourceLine() != UNMAPPED) {
                    String originalFile = sources[entry.getSourceFileId()];
                    if (!reverseSourceMapping.containsKey(originalFile)) {
                        reverseSourceMapping.put(originalFile, new HashMap<Integer, Collection<OriginalMapping>>());
                    }
                    Map<Integer, Collection<OriginalMapping>> lineToCollectionMap = reverseSourceMapping.get(originalFile);
                    int sourceLine = entry.getSourceLine();
                    if (!lineToCollectionMap.containsKey(sourceLine)) {
                        lineToCollectionMap.put(sourceLine, new ArrayList<OriginalMapping>(1));
                    }
                    Collection<OriginalMapping> mappings = lineToCollectionMap.get(sourceLine);
                    Builder builder = OriginalMapping.newBuilder().setLineNumber(targetLine).setColumnPosition(entry.getGeneratedColumn());
                    mappings.add(builder.build());
                }
            }
        }
    }
}
Also used : OriginalMapping(com.google.debugging.sourcemap.proto.Mapping.OriginalMapping) Builder(com.google.debugging.sourcemap.proto.Mapping.OriginalMapping.Builder) Collection(java.util.Collection)

Example 5 with OriginalMapping

use of com.google.debugging.sourcemap.proto.Mapping.OriginalMapping 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)13 Test (org.junit.Test)4 SourceMapConsumerV3 (com.google.debugging.sourcemap.SourceMapConsumerV3)3 Node (com.google.javascript.rhino.Node)3 GwtIncompatible (com.google.common.annotations.GwtIncompatible)2 FilePosition (com.google.debugging.sourcemap.FilePosition)2 JsonWriter (com.google.gson.stream.JsonWriter)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)2 IOException (java.io.IOException)2 OutputStreamWriter (java.io.OutputStreamWriter)2 TypeToken (com.google.common.reflect.TypeToken)1 Builder (com.google.debugging.sourcemap.proto.Mapping.OriginalMapping.Builder)1 Builder (com.google.javascript.jscomp.JsMessage.Builder)1 ErrorWithLevel (com.google.javascript.jscomp.SortingErrorManager.ErrorWithLevel)1 StaticSourceFile (com.google.javascript.rhino.StaticSourceFile)1 StringWriter (java.io.StringWriter)1 ArrayList (java.util.ArrayList)1 Collection (java.util.Collection)1 Nullable (javax.annotation.Nullable)1