public void testNullCoalescingAndConditionalOps() {
   SoyFileSetNode soyTree =
       SoyFileSetParserBuilder.forFileContents(
               constructTemplateSource(
                   "{@param pa: unknown}",
                   "{@param pi: int}",
                   "{@param pf: float}",
                   "{@param? ni: int}",
                   "{captureType($pa ?: $pi)}",
                   "{captureType($pi ?: $pf)}",
                   "{captureType($pa ? $pi : $pf)}",
                   "{captureType($ni ?: 0)}"))
           .declaredSyntaxVersion(SyntaxVersion.V2_0)
           .doRunInitialParsingPasses(false)
           .typeRegistry(typeRegistry)
           .parse()
           .fileSet();
   createResolveNamesVisitorForMaxSyntaxVersion().exec(soyTree);
   createResolveExpressionTypesVisitorForMaxSyntaxVersion().exec(soyTree);
   List<SoyType> types = getCapturedTypes(soyTree);
   assertThat(types.get(0)).isEqualTo(UnknownType.getInstance());
   assertThat(types.get(1))
       .isEqualTo(UnionType.of(IntType.getInstance(), FloatType.getInstance()));
   assertThat(types.get(2))
       .isEqualTo(UnionType.of(IntType.getInstance(), FloatType.getInstance()));
   assertThat(types.get(3)).isEqualTo(IntType.getInstance());
 }
示例#2
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 testArithmeticOps() {
    SoyFileSetNode soyTree =
        SoyFileSetParserBuilder.forFileContents(
                constructTemplateSource(
                    "{@param pa: unknown}",
                    "{@param pi: int}",
                    "{@param pf: float}",
                    "{@param ps: string}",
                    "{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)}",
                    "{captureType(-$pi)}",
                    "{captureType(-$pf)}",
                    // The remainder are all logically template errors but are not enforced by the
                    // compiler
                    "{captureType(-$ps)}",
                    "{captureType($ps / $pf)}"))
            .declaredSyntaxVersion(SyntaxVersion.V2_0)
            .typeRegistry(typeRegistry)
            .parse()
            .fileSet();
    createResolveNamesVisitorForMaxSyntaxVersion().exec(soyTree);
    createResolveExpressionTypesVisitorForMaxSyntaxVersion().exec(soyTree);
    List<SoyType> types = getCapturedTypes(soyTree);
    assertThat(types.get(0)).isEqualTo(UnknownType.getInstance());
    assertThat(types.get(1)).isEqualTo(IntType.getInstance());
    assertThat(types.get(2)).isEqualTo(FloatType.getInstance());
    assertThat(types.get(3)).isEqualTo(UnknownType.getInstance());
    assertThat(types.get(4)).isEqualTo(IntType.getInstance());
    assertThat(types.get(5)).isEqualTo(FloatType.getInstance());
    assertThat(types.get(6)).isEqualTo(UnknownType.getInstance());
    assertThat(types.get(7)).isEqualTo(IntType.getInstance());
    assertThat(types.get(8)).isEqualTo(FloatType.getInstance());
    assertThat(types.get(9)).isEqualTo(FloatType.getInstance());
    assertThat(types.get(10)).isEqualTo(FloatType.getInstance());
    assertThat(types.get(11)).isEqualTo(FloatType.getInstance());
    assertThat(types.get(12)).isEqualTo(UnknownType.getInstance());
    assertThat(types.get(13)).isEqualTo(IntType.getInstance());
    assertThat(types.get(14)).isEqualTo(FloatType.getInstance());
    assertThat(types.get(15)).isEqualTo(UnknownType.getInstance());
    assertThat(types.get(16)).isEqualTo(IntType.getInstance());
    assertThat(types.get(17)).isEqualTo(FloatType.getInstance());

    // These are the 'error' cases
    assertThat(types.get(18)).isEqualTo(UnknownType.getInstance());
    assertThat(types.get(19)).isEqualTo(UnknownType.getInstance());
  }
 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());
 }
示例#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 testListLiteral() {
   SoyFileSetNode soyTree =
       SoyFileSetParserBuilder.forFileContents(
               constructTemplateSource(
                   "{@param pi: int}",
                   "{@param pf: float}",
                   "{let $list: [$pi, $pf]/}",
                   "{$list}",
                   "{$list.length}"))
           .declaredSyntaxVersion(SyntaxVersion.V2_0)
           .doRunInitialParsingPasses(false)
           .typeRegistry(typeRegistry)
           .parse();
   createResolveNamesVisitorForMaxSyntaxVersion().exec(soyTree);
   createResolveExpressionTypesVisitorForMaxSyntaxVersion().exec(soyTree);
   List<SoyType> types = getPrintStatementTypes(soyTree);
   assertThat(types.get(0))
       .isEqualTo(ListType.of(UnionType.of(IntType.getInstance(), FloatType.getInstance())));
   assertThat(types.get(1)).isEqualTo(IntType.getInstance());
 }
示例#7
0
 public void testParseRecordTypes() {
   assertTypeEquals(
       RecordType.of(
           ImmutableMap.<String, SoyType>builder().put("a", IntType.getInstance()).build()),
       "[a:int]");
   assertTypeEquals(
       RecordType.of(
           ImmutableMap.<String, SoyType>builder()
               .put("a", IntType.getInstance())
               .put("b", FloatType.getInstance())
               .build()),
       "[a:int, b:float]");
   assertTypeEquals(
       RecordType.of(
           ImmutableMap.<String, SoyType>builder()
               .put("a", IntType.getInstance())
               .put("b", ListType.of(StringType.getInstance()))
               .build()),
       "[a:int, b:list<string>]");
 }
 public void testRecordTypes() {
   SoyFileSetNode soyTree =
       SoyFileSetParserBuilder.forFileContents(
               constructTemplateSource("{@param pa: [a:int, b:string]}", "{$pa.a}", "{$pa.b}"))
           .parse();
   createResolveNamesVisitorForMaxSyntaxVersion().exec(soyTree);
   createResolveExpressionTypesVisitorForMaxSyntaxVersion().exec(soyTree);
   List<SoyType> types = getPrintStatementTypes(soyTree);
   assertThat(types.get(0)).isEqualTo(IntType.getInstance());
   assertThat(types.get(1)).isEqualTo(StringType.getInstance());
 }
 public void testMapLiteral() {
   SoyFileSetNode soyTree =
       SoyFileSetParserBuilder.forFileContents(
               constructTemplateSource(
                   "{@param pi: int}",
                   "{@param pf: float}",
                   "{let $map: [1: $pi, 2:$pf]/}",
                   "{captureType($map)}"))
           .declaredSyntaxVersion(SyntaxVersion.V2_0)
           .typeRegistry(typeRegistry)
           .parse()
           .fileSet();
   createResolveNamesVisitorForMaxSyntaxVersion().exec(soyTree);
   createResolveExpressionTypesVisitorForMaxSyntaxVersion().exec(soyTree);
   SoyType type = Iterables.getOnlyElement(getCapturedTypes(soyTree));
   assertThat(type)
       .isEqualTo(
           MapType.of(
               IntType.getInstance(),
               UnionType.of(IntType.getInstance(), FloatType.getInstance())));
 }
 public void testDataFlowTypeNarrowing_complexExpressions() {
   SoyFileSetNode soyTree =
       SoyFileSetParserBuilder.forFileContents(
               constructTemplateSource(
                   "{@param map: map<string, int|null>}",
                   "{@param record: [a : [nullableInt : int|null, nullableBool : bool|null]|null]}",
                   "{@param pb: bool}",
                   "{if $map['a']}",
                   "  {$map['a']}",
                   "{/if}",
                   "{if $record.a?.nullableInt}",
                   "  {$record.a?.nullableInt}",
                   "{/if}",
                   ""))
           .parse();
   createResolveNamesVisitorForMaxSyntaxVersion().exec(soyTree);
   createResolveExpressionTypesVisitorForMaxSyntaxVersion().exec(soyTree);
   List<SoyType> types = getPrintStatementTypes(soyTree);
   assertThat(types.get(0)).isEqualTo(IntType.getInstance());
   assertThat(types.get(1)).isEqualTo(IntType.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 testNullCoalescingAndConditionalOps_complexCondition() {
   SoyFileSetNode soyTree =
       SoyFileSetParserBuilder.forFileContents(
               constructTemplateSource("{@param? l: [a :int]}", "{$l?.a ?: 0}"))
           .declaredSyntaxVersion(SyntaxVersion.V2_0)
           .doRunInitialParsingPasses(false)
           .typeRegistry(typeRegistry)
           .parse();
   createResolveNamesVisitorForMaxSyntaxVersion().exec(soyTree);
   createResolveExpressionTypesVisitorForMaxSyntaxVersion().exec(soyTree);
   List<SoyType> types = getPrintStatementTypes(soyTree);
   assertThat(types.get(0)).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 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 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())));
 }
 public void testArithmeticOps() {
   SoyFileSetNode soyTree =
       SoyFileSetParserBuilder.forFileContents(
               constructTemplateSource(
                   "{@param pa: unknown}",
                   "{@param pi: int}",
                   "{@param pf: float}",
                   "{$pa + $pa}",
                   "{$pi + $pi}",
                   "{$pf + $pf}",
                   "{$pa - $pa}",
                   "{$pi - $pi}",
                   "{$pf - $pf}",
                   "{$pa * $pa}",
                   "{$pi * $pi}",
                   "{$pf * $pf}",
                   "{$pa / $pa}",
                   "{$pi / $pi}",
                   "{$pf / $pf}",
                   "{$pa % $pa}",
                   "{$pi % $pi}",
                   "{$pf % $pf}",
                   "{-$pa}",
                   "{-$pi}",
                   "{-$pf}"))
           .declaredSyntaxVersion(SyntaxVersion.V2_0)
           .doRunInitialParsingPasses(false)
           .typeRegistry(typeRegistry)
           .parse();
   createResolveNamesVisitorForMaxSyntaxVersion().exec(soyTree);
   createResolveExpressionTypesVisitorForMaxSyntaxVersion().exec(soyTree);
   List<SoyType> types = getPrintStatementTypes(soyTree);
   assertThat(types.get(0)).isEqualTo(UnknownType.getInstance());
   assertThat(types.get(1)).isEqualTo(IntType.getInstance());
   assertThat(types.get(2)).isEqualTo(FloatType.getInstance());
   assertThat(types.get(3)).isEqualTo(UnknownType.getInstance());
   assertThat(types.get(4)).isEqualTo(IntType.getInstance());
   assertThat(types.get(5)).isEqualTo(FloatType.getInstance());
   assertThat(types.get(6)).isEqualTo(UnknownType.getInstance());
   assertThat(types.get(7)).isEqualTo(IntType.getInstance());
   assertThat(types.get(8)).isEqualTo(FloatType.getInstance());
   assertThat(types.get(9)).isEqualTo(UnknownType.getInstance());
   assertThat(types.get(10)).isEqualTo(IntType.getInstance());
   assertThat(types.get(11)).isEqualTo(FloatType.getInstance());
   assertThat(types.get(12)).isEqualTo(UnknownType.getInstance());
   assertThat(types.get(13)).isEqualTo(IntType.getInstance());
   assertThat(types.get(14)).isEqualTo(FloatType.getInstance());
   assertThat(types.get(15)).isEqualTo(UnknownType.getInstance());
   assertThat(types.get(16)).isEqualTo(IntType.getInstance());
   assertThat(types.get(17)).isEqualTo(FloatType.getInstance());
 }
 public void testMapLiteralAsRecord() {
   SoyFileSetNode soyTree =
       SoyFileSetParserBuilder.forFileContents(
               constructTemplateSource(
                   "{@param pi: int}",
                   "{@param pf: float}",
                   "{let $map: ['a': $pi, 'b':$pf]/}",
                   "{captureType($map)}"))
           .declaredSyntaxVersion(SyntaxVersion.V2_0)
           .typeRegistry(typeRegistry)
           .parse()
           .fileSet();
   createResolveNamesVisitorForMaxSyntaxVersion().exec(soyTree);
   createResolveExpressionTypesVisitorForMaxSyntaxVersion().exec(soyTree);
   List<SoyType> types = getCapturedTypes(soyTree);
   assertThat(types.get(0))
       .isEqualTo(
           RecordType.of(
               ImmutableMap.<String, SoyType>of(
                   "a", IntType.getInstance(), "b", FloatType.getInstance())));
 }
 public void testMapLiteralWithStringKeysAsMap() {
   SoyFileSetNode soyTree =
       SoyFileSetParserBuilder.forFileContents(
               constructTemplateSource(
                   "{@param v1: int}",
                   "{@param v2: string}",
                   "{@param k1: string}",
                   "{let $map: [$k1: $v1, 'b': $v2] /}",
                   "{$map}"))
           .declaredSyntaxVersion(SyntaxVersion.V2_0)
           .doRunInitialParsingPasses(false)
           .typeRegistry(typeRegistry)
           .parse();
   createResolveNamesVisitorForMaxSyntaxVersion().exec(soyTree);
   createResolveExpressionTypesVisitorForMaxSyntaxVersion().exec(soyTree);
   SoyType type = Iterables.getOnlyElement(getPrintStatementTypes(soyTree));
   assertThat(type)
       .isEqualTo(
           MapType.of(
               StringType.getInstance(),
               UnionType.of(StringType.getInstance(), IntType.getInstance())));
 }
示例#19
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>");
 }