Example #1
0
 public void testParseUnionTypes() {
   assertTypeEquals(UnionType.of(IntType.getInstance(), BoolType.getInstance()), "int|bool");
   assertTypeEquals(
       UnionType.of(IntType.getInstance(), BoolType.getInstance(), StringType.getInstance()),
       "int|bool|string");
   assertTypeEquals(UnionType.of(IntType.getInstance(), BoolType.getInstance()), " int | bool ");
 }
 public void testDataRefTypes() {
   SoyFileSetNode soyTree =
       SoyFileSetParserBuilder.forFileContents(
               constructTemplateSource(
                   "{@param pa: bool}",
                   "{@param pb: list<int>}",
                   "{@param pe: map<int, map<int, string>>}",
                   "{captureType($pa)}",
                   "{captureType($pb)}",
                   "{captureType($pb[0])}",
                   "{captureType($pe)}",
                   "{captureType($pe[0])}",
                   "{captureType($pe[1 + 1][2])}"))
           .parse()
           .fileSet();
   createResolveNamesVisitorForMaxSyntaxVersion().exec(soyTree);
   createResolveExpressionTypesVisitorForMaxSyntaxVersion().exec(soyTree);
   List<SoyType> types = getCapturedTypes(soyTree);
   assertThat(types.get(0)).isEqualTo(BoolType.getInstance());
   assertThat(types.get(1)).isEqualTo(ListType.of(IntType.getInstance()));
   assertThat(types.get(2)).isEqualTo(IntType.getInstance());
   assertThat(types.get(3))
       .isEqualTo(
           MapType.of(
               IntType.getInstance(),
               MapType.of(IntType.getInstance(), StringType.getInstance())));
   assertThat(types.get(4)).isEqualTo(MapType.of(IntType.getInstance(), StringType.getInstance()));
   assertThat(types.get(5)).isEqualTo(StringType.getInstance());
 }
 public void testDataFlowTypeNarrowingFailure() {
   // Test for places where type narrowing shouldn't work
   SoyType boolOrNullType = makeNullable(BoolType.getInstance());
   SoyFileSetNode soyTree =
       SoyFileSetParserBuilder.forFileContents(
               constructTemplateSource(
                   "{@param pa: bool|null}",
                   "{@param pb: bool}",
                   "{if ($pa != null) != ($pb != null)}",
                   "  {captureType($pa)}", // #0 don't know
                   "{else}",
                   "  {captureType($pa)}", // #1 don't know
                   "{/if}",
                   "{if $pa ?: $pb}",
                   "  {captureType($pa)}", // #2 don't know
                   "{/if}",
                   "{if $pb ? $pa : false}",
                   "  {captureType($pa)}", // #3 don't know
                   "{/if}"))
           .parse()
           .fileSet();
   createResolveNamesVisitorForMaxSyntaxVersion().exec(soyTree);
   createResolveExpressionTypesVisitorForMaxSyntaxVersion().exec(soyTree);
   List<SoyType> types = getCapturedTypes(soyTree);
   assertThat(types.get(0)).isEqualTo(boolOrNullType);
   assertThat(types.get(1)).isEqualTo(boolOrNullType);
   assertThat(types.get(2)).isEqualTo(boolOrNullType);
   assertThat(types.get(3)).isEqualTo(boolOrNullType);
 }
 public void testComparisonOps() {
   SoyFileSetNode soyTree =
       SoyFileSetParserBuilder.forFileContents(
               constructTemplateSource(
                   "{@param pa: unknown}",
                   "{@param pi: int}",
                   "{@param pf: float}",
                   "{captureType($pa > $pa)}",
                   "{captureType($pi > $pi)}",
                   "{captureType($pf > $pf)}",
                   "{captureType($pa >= $pa)}",
                   "{captureType($pi >= $pi)}",
                   "{captureType($pf >= $pf)}",
                   "{captureType($pa < $pa)}",
                   "{captureType($pi < $pi)}",
                   "{captureType($pf < $pf)}",
                   "{captureType($pa <= $pa)}",
                   "{captureType($pi <= $pi)}",
                   "{captureType($pf <= $pf)}",
                   "{captureType($pa == $pa)}",
                   "{captureType($pi == $pi)}",
                   "{captureType($pf == $pf)}",
                   "{captureType($pa != $pa)}",
                   "{captureType($pi != $pi)}",
                   "{captureType($pf != $pf)}"))
           .declaredSyntaxVersion(SyntaxVersion.V2_0)
           .doRunInitialParsingPasses(false)
           .typeRegistry(typeRegistry)
           .parse()
           .fileSet();
   createResolveNamesVisitorForMaxSyntaxVersion().exec(soyTree);
   createResolveExpressionTypesVisitorForMaxSyntaxVersion().exec(soyTree);
   ImmutableSet<SoyType> types = ImmutableSet.copyOf(getCapturedTypes(soyTree));
   assertThat(types).containsExactly(BoolType.getInstance());
 }
Example #5
0
 public void testParseTypeNames() {
   assertTypeEquals(AnyType.getInstance(), "any");
   assertTypeEquals(AnyType.getInstance(), " any ");
   assertTypeEquals(IntType.getInstance(), "int");
   assertTypeEquals(BoolType.getInstance(), "bool");
   assertTypeEquals(FOO_BAR_TYPE, "foo.bar");
   assertTypeEquals(FOO_BAR_TYPE, " foo.bar ");
   assertTypeEquals(FOO_BAR_TYPE, " foo . bar ");
   assertTypeEquals(UnknownType.getInstance(), "?");
 }
 public void testDataFlowTypeNarrowing_logicalExpressions() {
   SoyFileSetNode soyTree =
       SoyFileSetParserBuilder.forFileContents(
               constructTemplateSource(
                   "{@param? record: [active : bool|null]}",
                   "{@param? selected: map<string,bool>}",
                   "{$selected and $selected['a']}",
                   "{$selected == null or $selected['a']}",
                   "{if isNonnull($record.active) and (not $record.active)}",
                   "  {$record.active}",
                   "{/if}",
                   ""))
           .parse();
   createResolveNamesVisitorForMaxSyntaxVersion().exec(soyTree);
   createResolveExpressionTypesVisitorForMaxSyntaxVersion().exec(soyTree);
   List<SoyType> types = getPrintStatementTypes(soyTree);
   assertThat(types.get(0)).isEqualTo(BoolType.getInstance());
   assertThat(types.get(1)).isEqualTo(BoolType.getInstance());
   assertThat(types.get(2)).isEqualTo(BoolType.getInstance());
 }
 public void testOptionalParamTypes() {
   SoyFileSetNode soyTree =
       SoyFileSetParserBuilder.forFileContents(
               constructTemplateSource(
                   "{@param? pa: bool}", "{@param? pb: list<int>}", "{$pa}", "{$pb}"))
           .parse();
   createResolveNamesVisitorForMaxSyntaxVersion().exec(soyTree);
   createResolveExpressionTypesVisitorForMaxSyntaxVersion().exec(soyTree);
   List<SoyType> types = getPrintStatementTypes(soyTree);
   assertThat(types.get(0)).isEqualTo(makeNullable(BoolType.getInstance()));
   assertThat(types.get(1)).isEqualTo(makeNullable(ListType.of(IntType.getInstance())));
 }
 public void testFunctionTyping() {
   SoyFileSetNode soyTree =
       SoyFileSetParserBuilder.forFileContents(
               constructTemplateSource(
                   "{@inject list: list<int|null>}",
                   "{foreach $item in $list}",
                   "   {index($item)}",
                   "   {isLast($item)}",
                   "   {isFirst($item)}",
                   "   {$item}",
                   "   {checkNotNull($item)}",
                   "{/foreach}"))
           .parse();
   createResolveNamesVisitorForMaxSyntaxVersion().exec(soyTree);
   createResolveExpressionTypesVisitorForMaxSyntaxVersion().exec(soyTree);
   List<SoyType> types = getPrintStatementTypes(soyTree);
   assertThat(types.get(0)).isEqualTo(IntType.getInstance());
   assertThat(types.get(1)).isEqualTo(BoolType.getInstance());
   assertThat(types.get(2)).isEqualTo(BoolType.getInstance());
   assertThat(types.get(3)).isEqualTo(makeNullable(IntType.getInstance()));
   assertThat(types.get(4)).isEqualTo(IntType.getInstance());
 }
 public void testConditionalOperatorDataFlowTypeNarrowing() {
   SoyFileSetNode soyTree =
       SoyFileSetParserBuilder.forFileContents(
               constructTemplateSource(
                   "{@param pa: bool|null}",
                   "{@param pb: bool}",
                   "{@param pc: [a : int|null]}",
                   "{$pa ? $pa : $pb}", // #0 must be non-null
                   "{$pa != null ?: $pb}", // #1 must be non-null
                   "{$pa ?: $pb}",
                   "{$pc.a ? $pc.a : 0}",
                   "{if not $pc.a}{$pc.a}{/if}"))
           .parse(); // #2 must be non-null (re-written to (isNonnull($pa) ? $pa : $pb))
   createResolveNamesVisitorForMaxSyntaxVersion().exec(soyTree);
   createResolveExpressionTypesVisitorForMaxSyntaxVersion().exec(soyTree);
   List<SoyType> types = getPrintStatementTypes(soyTree);
   assertThat(types.get(0)).isEqualTo(BoolType.getInstance());
   assertThat(types.get(1)).isEqualTo(BoolType.getInstance());
   assertThat(types.get(2)).isEqualTo(BoolType.getInstance());
   assertThat(types.get(3)).isEqualTo(IntType.getInstance());
   assertThat(types.get(4)).isEqualTo(makeNullable(IntType.getInstance()));
 }
 public void testInjectedParamTypes() {
   SoyFileSetNode soyTree =
       SoyFileSetParserBuilder.forFileContents(
               constructTemplateSource(
                   "{@inject pa: bool}",
                   "{@inject? pb: list<int>}",
                   "{captureType($pa)}",
                   "{captureType($pb)}"))
           .parse()
           .fileSet();
   createResolveNamesVisitorForMaxSyntaxVersion().exec(soyTree);
   createResolveExpressionTypesVisitorForMaxSyntaxVersion().exec(soyTree);
   List<SoyType> types = getCapturedTypes(soyTree);
   assertThat(types.get(0)).isEqualTo(BoolType.getInstance());
   assertThat(types.get(1)).isEqualTo(makeNullable(ListType.of(IntType.getInstance())));
 }
Example #11
0
 public void testParameterizedTypes() {
   assertTypeEquals(ListType.of(StringType.getInstance()), "list<string>");
   assertTypeEquals(ListType.of(StringType.getInstance()), "list < string > ");
   assertTypeEquals(MapType.of(IntType.getInstance(), BoolType.getInstance()), "map<int, bool>");
 }
Example #12
0
 @Override
 public SoyType getType() {
   return BoolType.getInstance();
 }
  public void testDataFlowTypeNarrowing() {
    SoyType boolOrNullType = makeNullable(BoolType.getInstance());
    SoyFileSetNode soyTree =
        SoyFileSetParserBuilder.forFileContents(
                constructTemplateSource(
                    "{@param pa: bool|null}",
                    "{@param pb: bool}",
                    "{if $pa != null}",
                    "  {captureType($pa)}", // #0 must be non-null
                    "{/if}",
                    "{if $pa == null}",
                    "  {captureType($pa)}", // #1 must be null
                    "{else}",
                    "  {captureType($pa)}", // #2 must be non-null
                    "{/if}",
                    "{if $pa == null or $pb}",
                    "  {captureType($pa)}", // #3 don't know
                    "{else}",
                    "  {captureType($pa)}", // #4 must be non-null
                    "{/if}",
                    "{if $pa == null and $pb}",
                    "  {captureType($pa)}", // #5 must be null
                    "{else}",
                    "  {captureType($pa)}", // #6 don't know
                    "{/if}",
                    "{if null != $pa}", // Reverse order
                    "  {captureType($pa)}", // #7 must be non-null
                    "{/if}",
                    "{if not ($pa == null)}", // Not operator
                    "  {captureType($pa)}", // #8 must be non-null
                    "{/if}",
                    "{if $pa}", // Implicit != null
                    "  {captureType($pa)}", // #9 must be non-null
                    "{/if}",
                    "{if $pa and $pb}", // Implicit != null
                    "  {captureType($pa)}", // #10 must be non-null
                    "{/if}",
                    "{if $pa}", // Chained conditions
                    "{elseif $pb}",
                    "  {captureType($pa)}", // #11 must be falsy
                    "{else}",
                    "  {captureType($pa)}", // #12 must be falsy
                    "{/if}",
                    "{if $pa}", // Nested if
                    "  {if $pa}",
                    "    {captureType($pa)}", // #13 must be non-null
                    "  {/if}",
                    "{/if}",
                    "{if isNonnull($pa)}", // isNonnull function
                    "  {captureType($pa)}", // #14 must be non-null
                    "{else}",
                    "  {captureType($pa)}", // #15 must be null
                    "{/if}",
                    "{if $pb or $pa == null}",
                    "  {captureType($pa)}", // #16 don't know
                    "{else}",
                    "  {captureType($pa)}", // #17 must be null
                    "{/if}",
                    // TODO(lukes): uncomment this and fix the error
                    // "{if null == null or null != null}{/if}",
                    ""))
            .parse()
            .fileSet();
    createResolveNamesVisitorForMaxSyntaxVersion().exec(soyTree);
    createResolveExpressionTypesVisitorForMaxSyntaxVersion().exec(soyTree);
    List<SoyType> types = getCapturedTypes(soyTree);
    assertThat(types.get(0)).isEqualTo(BoolType.getInstance());
    assertThat(types.get(1)).isEqualTo(NullType.getInstance());
    assertThat(types.get(2)).isEqualTo(BoolType.getInstance());
    assertThat(types.get(3)).isEqualTo(boolOrNullType);
    assertThat(types.get(4)).isEqualTo(BoolType.getInstance());
    assertThat(types.get(5)).isEqualTo(NullType.getInstance());
    assertThat(types.get(6)).isEqualTo(boolOrNullType);
    assertThat(types.get(7)).isEqualTo(BoolType.getInstance());
    assertThat(types.get(8)).isEqualTo(BoolType.getInstance());
    assertThat(types.get(9)).isEqualTo(BoolType.getInstance());
    assertThat(types.get(10)).isEqualTo(BoolType.getInstance());
    assertThat(types.get(11)).isEqualTo(makeNullable(BoolType.getInstance()));
    assertThat(types.get(12)).isEqualTo(makeNullable(BoolType.getInstance()));
    assertThat(types.get(13)).isEqualTo(BoolType.getInstance());
    assertThat(types.get(14)).isEqualTo(BoolType.getInstance());
    assertThat(types.get(15)).isEqualTo(NullType.getInstance());

    assertThat(types.get(16)).isEqualTo(makeNullable(BoolType.getInstance()));
    assertThat(types.get(17)).isEqualTo(BoolType.getInstance());
  }
  public void testLogicalOps() {
    String testTemplateContent =
        constructTemplateSource(
            "{@param pa: unknown}",
            "{@param pi: int}",
            "{@param pf: float}",
            "{captureType($pa and $pa)}",
            "{captureType($pi and $pi)}",
            "{captureType($pf and $pf)}",
            "{captureType($pa or $pa)}",
            "{captureType($pi or $pi)}",
            "{captureType($pf or $pf)}",
            "{captureType(not $pa)}",
            "{captureType(not $pi)}",
            "{captureType(not $pf)}");

    SoyFileSetNode soyTree =
        SoyFileSetParserBuilder.forFileContents(testTemplateContent)
            .declaredSyntaxVersion(SyntaxVersion.V2_0)
            .doRunInitialParsingPasses(false)
            .typeRegistry(typeRegistry)
            .parse()
            .fileSet();
    createResolveNamesVisitor(SyntaxVersion.V2_0).exec(soyTree);
    createResolveExpressionTypesVisitor(SyntaxVersion.V2_0).exec(soyTree);
    List<SoyType> types = getCapturedTypes(soyTree);
    assertThat(types.get(0)).isEqualTo(UnknownType.getInstance());
    assertThat(types.get(1)).isEqualTo(UnknownType.getInstance());
    assertThat(types.get(2)).isEqualTo(UnknownType.getInstance());
    assertThat(types.get(3)).isEqualTo(UnknownType.getInstance());
    assertThat(types.get(4)).isEqualTo(UnknownType.getInstance());
    assertThat(types.get(5)).isEqualTo(UnknownType.getInstance());
    assertThat(types.get(6)).isEqualTo(BoolType.getInstance());
    assertThat(types.get(7)).isEqualTo(BoolType.getInstance());
    assertThat(types.get(8)).isEqualTo(BoolType.getInstance());

    soyTree =
        SoyFileSetParserBuilder.forFileContents(testTemplateContent)
            .declaredSyntaxVersion(SyntaxVersion.V2_3)
            .doRunInitialParsingPasses(false)
            .typeRegistry(typeRegistry)
            .parse()
            .fileSet();
    createResolveNamesVisitor(SyntaxVersion.V2_3).exec(soyTree);
    createResolveExpressionTypesVisitor(SyntaxVersion.V2_3).exec(soyTree);
    types = getCapturedTypes(soyTree);
    assertThat(types.get(0)).isEqualTo(BoolType.getInstance());
    assertThat(types.get(1)).isEqualTo(BoolType.getInstance());
    assertThat(types.get(2)).isEqualTo(BoolType.getInstance());
    assertThat(types.get(3)).isEqualTo(BoolType.getInstance());
    assertThat(types.get(4)).isEqualTo(BoolType.getInstance());
    assertThat(types.get(5)).isEqualTo(BoolType.getInstance());
    assertThat(types.get(6)).isEqualTo(BoolType.getInstance());
    assertThat(types.get(7)).isEqualTo(BoolType.getInstance());
    assertThat(types.get(8)).isEqualTo(BoolType.getInstance());
  }