Search in sources :

Example 6 with SourceLocation

use of com.google.template.soy.base.SourceLocation in project closure-templates by google.

the class TemplateNodeBuilder method setCommonCommandValues.

protected void setCommonCommandValues(List<CommandTagAttribute> attrs) {
    AutoescapeMode autoescapeMode = soyFileHeaderInfo.defaultAutoescapeMode;
    SanitizedContentKind kind = null;
    SourceLocation kindLocation = null;
    for (CommandTagAttribute attribute : attrs) {
        Identifier name = attribute.getName();
        switch(name.identifier()) {
            case "autoescape":
                autoescapeMode = attribute.valueAsAutoescapeMode(errorReporter);
                break;
            case "kind":
                kind = attribute.valueAsContentKind(errorReporter);
                kindLocation = attribute.getValueLocation();
                if (kind == SanitizedContentKind.HTML) {
                    errorReporter.report(kindLocation, CommandTagAttribute.EXPLICIT_DEFAULT_ATTRIBUTE, "kind", "html");
                }
                break;
            case "requirecss":
                setRequiredCssNamespaces(attribute.valueAsRequireCss(errorReporter));
                break;
            case "cssbase":
                setCssBaseNamespace(attribute.valueAsCssBase(errorReporter));
                break;
            case "deprecatedV1":
                markDeprecatedV1(attribute.valueAsEnabled(errorReporter));
                break;
            case "stricthtml":
                strictHtmlDisabled = attribute.valueAsDisabled(errorReporter);
                break;
            default:
                break;
        }
    }
    setAutoescapeInfo(autoescapeMode, kind, kindLocation);
}
Also used : SourceLocation(com.google.template.soy.base.SourceLocation) Identifier(com.google.template.soy.base.internal.Identifier) SanitizedContentKind(com.google.template.soy.base.internal.SanitizedContentKind)

Example 7 with SourceLocation

use of com.google.template.soy.base.SourceLocation in project closure-templates by google.

the class TemplateNodeBuilder method parseSoyDocDeclsHelper.

/**
 * Private helper for the constructor to parse the SoyDoc declarations.
 *
 * @param cleanedSoyDoc The cleaned SoyDoc text. Must not be null.
 * @return A SoyDocDeclsInfo object with the parsed info.
 */
private List<SoyDocParam> parseSoyDocDeclsHelper(String originalSoyDoc, String cleanedSoyDoc, SourceLocation soyDocSourceLocation) {
    List<SoyDocParam> params = new ArrayList<>();
    RawTextNode originalSoyDocAsNode = new RawTextNode(-1, originalSoyDoc, soyDocSourceLocation);
    Matcher matcher = SOY_DOC_DECL_PATTERN.matcher(cleanedSoyDoc);
    // Important: This statement finds the param for the first iteration of the loop.
    boolean isFound = matcher.find();
    while (isFound) {
        // Save the match groups.
        String declKeyword = matcher.group(1);
        String declText = matcher.group(2);
        String fullMatch = matcher.group();
        // find the param in the original soy doc and use the RawTextNode support for
        // calculating substring locations to get a more accurate location
        int indexOfParamName = originalSoyDoc.indexOf(declText, originalSoyDoc.indexOf(fullMatch));
        SourceLocation paramLocation = originalSoyDocAsNode.substringLocation(indexOfParamName, indexOfParamName + declText.length());
        // Find the next declaration in the SoyDoc and extract this declaration's desc string.
        int descStart = matcher.end();
        // Important: This statement finds the param for the next iteration of the loop.
        // We must find the next param now in order to know where the current param's desc ends.
        isFound = matcher.find();
        int descEnd = (isFound) ? matcher.start() : cleanedSoyDoc.length();
        String desc = cleanedSoyDoc.substring(descStart, descEnd).trim();
        if (declKeyword.equals("@param") || declKeyword.equals("@param?")) {
            if (SOY_DOC_PARAM_TEXT_PATTERN.matcher(declText).matches()) {
                params.add(new SoyDocParam(declText, declKeyword.equals("@param"), desc, paramLocation));
            } else {
                if (declText.startsWith("{")) {
                    // v1 is allowed for compatibility reasons
                    if (!isMarkedV1) {
                        errorReporter.report(paramLocation, LEGACY_COMPATIBLE_PARAM_TAG, declText);
                    }
                } else {
                    errorReporter.report(paramLocation, INVALID_SOYDOC_PARAM, declText);
                }
            }
        } else {
            throw new AssertionError();
        }
    }
    return params;
}
Also used : SourceLocation(com.google.template.soy.base.SourceLocation) Matcher(java.util.regex.Matcher) CharMatcher(com.google.common.base.CharMatcher) ArrayList(java.util.ArrayList) SoyDocParam(com.google.template.soy.soytree.defn.SoyDocParam)

Example 8 with SourceLocation

use of com.google.template.soy.base.SourceLocation in project closure-templates by google.

the class ParseErrors method reportSoyFileParseException.

static void reportSoyFileParseException(ErrorReporter reporter, String filePath, ParseException e, int currentLexicalState) {
    Token currentToken = e.currentToken;
    // currentToken is the 'last successfully consumed token', but the error is usually due to the
    // first unsuccessful token.  use that for the source location
    Token errorToken = (currentToken.next != null) ? currentToken.next : currentToken;
    SourceLocation location = Tokens.createSrcLoc(filePath, errorToken);
    String optionalAdvice = "";
    // handle a few special cases.
    switch(errorToken.kind) {
        case SoyFileParserConstants.XXX_BRACE_INVALID:
            reporter.report(location, UNEXPECTED_RIGHT_BRACE);
            return;
        case SoyFileParserConstants.DECL_BEGIN_PARAM:
        case SoyFileParserConstants.DECL_BEGIN_OPT_PARAM:
        case SoyFileParserConstants.DECL_BEGIN_INJECT_PARAM:
        case SoyFileParserConstants.DECL_BEGIN_OPT_INJECT_PARAM:
            reporter.report(location, UNEXPECTED_PARAM_DECL);
            return;
        case SoyFileParserConstants.LEGACY_AND:
            reporter.report(location, LEGACY_AND_ERROR);
            return;
        case SoyFileParserConstants.LEGACY_OR:
            reporter.report(location, LEGACY_OR_ERROR);
            return;
        case SoyFileParserConstants.LEGACY_NOT:
            reporter.report(location, LEGACY_NOT_ERROR);
            return;
        case SoyFileParserConstants.UNEXPECTED_DOUBLE_BRACE:
            reporter.report(location, FOUND_DOUBLE_BRACE);
            return;
        case SoyFileParserConstants.UNEXPECTED_CLOSE_TAG:
            reporter.report(location, UNEXPECTED_CLOSE_TAG);
            return;
        case SoyFileParserConstants.UNEXPECTED_ALIAS:
        case SoyFileParserConstants.UNEXPECTED_NAMESPACE:
        case SoyFileParserConstants.UNEXPECTED_DELPACKAGE:
        case SoyFileParserConstants.UNEXPECTED_TEMPLATE:
        case SoyFileParserConstants.UNEXPECTED_DELTEMPLATE:
            reporter.report(location, INVALID_TEMPLATE_COMMAND, errorToken.image);
            return;
        case SoyFileParserConstants.UNEXPECTED_NEWLINE:
            reporter.report(location, UNEXPECTED_NEWLINE);
            return;
        case SoyFileParserConstants.EOF:
            // The image for this token is usually pointing at some whitespace, which is confusing
            errorToken.image = "eof";
            if (currentLexicalState == SoyFileParserConstants.IN_DQ_ATTRIBUTE_VALUE || currentLexicalState == SoyFileParserConstants.IN_SQ_ATTRIBUTE_VALUE) {
                optionalAdvice = ". Did you forget to close an attribute?";
            } else if (currentLexicalState == SoyFileParserConstants.IN_MULTILINE_COMMENT || currentLexicalState == SoyFileParserConstants.IN_SOYDOC) {
                optionalAdvice = ". Did you forget to close a comment?";
            }
        // fall-through
        default:
    }
    ImmutableSet.Builder<String> expectedTokenImages = ImmutableSet.builder();
    for (int[] expected : e.expectedTokenSequences) {
        // TODO(lukes): scrub velog from error messages until it is released
        if (expected[0] == SoyFileParserConstants.CMD_BEGIN_VELOG) {
            continue;
        }
        // We only display the first token of any expected sequence
        String displayName = getSoyFileParserTokenDisplayName(expected[0]);
        if (displayName != null) {
            expectedTokenImages.add(displayName);
        }
    }
    reporter.report(location, PLAIN_ERROR, formatParseExceptionDetails(errorToken.image, expectedTokenImages.build().asList()) + optionalAdvice);
}
Also used : SourceLocation(com.google.template.soy.base.SourceLocation) ImmutableSet(com.google.common.collect.ImmutableSet)

Example 9 with SourceLocation

use of com.google.template.soy.base.SourceLocation in project closure-templates by google.

the class SourceLocationTest method testRawTextSourceLocations.

@Test
public void testRawTextSourceLocations() throws Exception {
    // RawTextNode has some special methods to calculating the source location of characters within
    // the strings, test those
    String template = JOINER.join("{namespace ns}", "{template .foo}", "  Hello,{sp}", "  {\\n}{nil}<span>Bob</span>", "  // and end of line comment", "  !", "  What's /*hello comment world*/up?", "{/template}", "");
    RawTextNode rawText = (RawTextNode) SoyFileSetParserBuilder.forFileContents(template).parse().fileSet().getChild(0).getChild(0).getChild(0);
    assertThat(rawText.getRawText()).isEqualTo("Hello, \n<span>Bob</span>! What's up?");
    assertThat(rawText.getRawText().substring(0, 5)).isEqualTo("Hello");
    SourceLocation loc = rawText.substringLocation(0, 5);
    assertThat(loc.getBeginLine()).isEqualTo(3);
    assertThat(loc.getBeginColumn()).isEqualTo(3);
    assertThat(loc.getEndLine()).isEqualTo(3);
    assertThat(loc.getEndColumn()).isEqualTo(7);
    assertThat(rawText.getRawText().substring(8, 14)).isEqualTo("<span>");
    loc = rawText.substringLocation(8, 14);
    assertThat(loc.getBeginLine()).isEqualTo(4);
    assertThat(loc.getBeginColumn()).isEqualTo(12);
    assertThat(loc.getEndLine()).isEqualTo(4);
    assertThat(loc.getEndColumn()).isEqualTo(17);
    assertThat(rawText.getRawText().substring(24, 25)).isEqualTo("!");
    loc = rawText.substringLocation(24, 25);
    assertThat(loc.getBeginLine()).isEqualTo(6);
    assertThat(loc.getBeginColumn()).isEqualTo(3);
    assertThat(loc.getEndLine()).isEqualTo(6);
    assertThat(loc.getEndColumn()).isEqualTo(3);
    assertThat(rawText.getRawText().substring(33, 36)).isEqualTo("up?");
    loc = rawText.substringLocation(33, 36);
    assertThat(loc.getBeginLine()).isEqualTo(7);
    assertThat(loc.getBeginColumn()).isEqualTo(33);
    assertThat(loc.getEndLine()).isEqualTo(7);
    assertThat(loc.getEndColumn()).isEqualTo(35);
    // doesn't matter
    final int id = 1337;
    RawTextNode subStringNode = rawText.substring(id, 0, 5);
    assertThat(subStringNode.getRawText()).isEqualTo("Hello");
    loc = subStringNode.getSourceLocation();
    assertThat(loc.getBeginLine()).isEqualTo(3);
    assertThat(loc.getBeginColumn()).isEqualTo(3);
    assertThat(loc.getEndLine()).isEqualTo(3);
    assertThat(loc.getEndColumn()).isEqualTo(7);
    subStringNode = rawText.substring(id, 24, 25);
    assertThat(subStringNode.getRawText()).isEqualTo("!");
    loc = subStringNode.getSourceLocation();
    assertThat(loc.getBeginLine()).isEqualTo(6);
    assertThat(loc.getBeginColumn()).isEqualTo(3);
    assertThat(loc.getEndLine()).isEqualTo(6);
    assertThat(loc.getEndColumn()).isEqualTo(3);
    // Can't create empty raw text nodes.
    try {
        rawText.substring(id, 24, 24);
        fail();
    } catch (IllegalArgumentException expected) {
    }
    try {
        rawText.substring(id, 24, 23);
        fail();
    } catch (IllegalArgumentException expected) {
    }
    try {
        rawText.substring(id, 24, Integer.MAX_VALUE);
        fail();
    } catch (IllegalArgumentException expected) {
    }
}
Also used : SourceLocation(com.google.template.soy.base.SourceLocation) RawTextNode(com.google.template.soy.soytree.RawTextNode) Test(org.junit.Test)

Example 10 with SourceLocation

use of com.google.template.soy.base.SourceLocation in project closure-templates by google.

the class SourceLocationTest method testAdditionalSourceLocationInfo.

@Test
public void testAdditionalSourceLocationInfo() throws Exception {
    String template = JOINER.join("{namespace ns}", "{template .t}", "  hello, world", "{/template}");
    TemplateNode templateNode = SoyFileSetParserBuilder.forFileContents(template).parse().fileSet().getChild(0).getChild(0);
    SourceLocation location = templateNode.getSourceLocation();
    // Begin at {template
    assertEquals(2, location.getBeginLine());
    assertEquals(1, location.getBeginColumn());
    // End after .t}
    assertEquals(2, location.getEndLine());
    assertEquals(13, location.getEndColumn());
}
Also used : TemplateNode(com.google.template.soy.soytree.TemplateNode) SourceLocation(com.google.template.soy.base.SourceLocation) Test(org.junit.Test)

Aggregations

SourceLocation (com.google.template.soy.base.SourceLocation)23 Test (org.junit.Test)8 VarRefNode (com.google.template.soy.exprtree.VarRefNode)5 TemplateNode (com.google.template.soy.soytree.TemplateNode)4 IntegerNode (com.google.template.soy.exprtree.IntegerNode)3 Matcher (java.util.regex.Matcher)3 CharMatcher (com.google.common.base.CharMatcher)2 ExprNode (com.google.template.soy.exprtree.ExprNode)2 FunctionNode (com.google.template.soy.exprtree.FunctionNode)2 NullNode (com.google.template.soy.exprtree.NullNode)2 HtmlOpenTagNode (com.google.template.soy.soytree.HtmlOpenTagNode)2 PrintNode (com.google.template.soy.soytree.PrintNode)2 RawTextNode (com.google.template.soy.soytree.RawTextNode)2 TemplateParam (com.google.template.soy.soytree.defn.TemplateParam)2 ArrayList (java.util.ArrayList)2 HashSet (java.util.HashSet)2 ImmutableSet (com.google.common.collect.ImmutableSet)1 Point (com.google.template.soy.base.SourceLocation.Point)1 Identifier (com.google.template.soy.base.internal.Identifier)1 SanitizedContentKind (com.google.template.soy.base.internal.SanitizedContentKind)1