public void testClassLineNumbers() {
    String content =
        "class foobar;\n"
            + // 1
            "    int a;\n"
            + // 2
            "    int b;\n"
            + // 3
            "\n"
            + // 4
            "endclass\n"
            + // 5
            "\n"
            + // 6
            "\n" // 7
        ;
    SVDBFile file = SVDBTestUtils.parse(content, "testClassStringFields");

    SVDBClassDecl cls = null;

    assertEquals("Wrong number of file elements", 1, SVDBUtil.getChildrenSize(file));

    cls = (SVDBClassDecl) SVDBUtil.getFirstChildItem(file);

    assertNotNull("Start location not specified", cls.getLocation());
    assertNotNull("End location not specified", cls.getEndLocation());

    assertEquals("Wrong start location", 1, cls.getLocation().getLine());
    assertEquals("Wrong end location", 5, cls.getEndLocation().getLine());
  }
  public void testEmptyConstraint() {
    String content =
        "class foobar;\n"
            + "\n"
            + "\n"
            + "    int a, b, c;\n"
            + "\n"
            + "    constraint empty_c {}\n"
            + "\n"
            + "endclass\n";

    SVDBFile file = SVDBTestUtils.parse(content, "testEmptyConstraint");

    SVDBClassDecl foobar = null;
    for (ISVDBItemBase it : file.getChildren()) {
      if (SVDBItem.getName(it).equals("foobar")) {
        foobar = (SVDBClassDecl) it;
        break;
      }
    }

    assertNotNull(foobar);

    SVDBConstraint empty_c = null;
    for (ISVDBItemBase it : foobar.getChildren()) {
      if (SVDBItem.getName(it).equals("empty_c")) {
        empty_c = (SVDBConstraint) it;
      }
    }

    assertNotNull(empty_c);
  }
  public void testCovergroup() {
    String content =
        "class foobar;\n"
            + "\n"
            + "\n"
            + "    int a, b, c;\n"
            + "\n"
            + "    covergroup cg;\n"
            + "        a_cp : coverpoint a;\n"
            + "        b_cp : coverpoint b {\n"
            + "            bins b[] = {[2:10]};\n"
            + "        }\n"
            + "        a_b_cross : cross a_cp, b_cp;\n"
            + "    endgroup\n"
            + "\n"
            + "    covergroup cg2;\n"
            + "        a_cp : coverpoint a;\n"
            + "        b_cp : coverpoint b {\n"
            + "            bins b[] = {[2:10]};\n"
            + "        }\n"
            + "        a_b_cross : cross a_cp, b_cp;\n"
            + "    endgroup\n"
            + "\n"
            + "endclass\n";
    SVCorePlugin.getDefault().enableDebug(false);

    SVDBFile file = SVDBTestUtils.parse(content, "testClassStringFields");

    SVDBClassDecl foobar = null;
    for (ISVDBItemBase it : file.getChildren()) {
      if (SVDBItem.getName(it).equals("foobar")) {
        foobar = (SVDBClassDecl) it;
        break;
      }
    }

    assertNotNull(foobar);

    SVDBCovergroup cg = null, cg2 = null;
    for (ISVDBItemBase it : foobar.getChildren()) {
      if (SVDBItem.getName(it).equals("cg")) {
        cg = (SVDBCovergroup) it;
      } else if (SVDBItem.getName(it).equals("cg2")) {
        cg2 = (SVDBCovergroup) it;
      }
    }

    assertNotNull(cg);
    assertNotNull(cg2);
  }
  public void testTypedefClass() {
    String content =
        "class foobar;\n"
            + "\n"
            + "    typedef class other_foo_t;\n"
            + "    typedef class other_foo_t1;\n"
            + "    typedef class other_foo_t2;\n"
            + "    typedef class other_foo_t3;\n"
            + "    typedef class other_foo_t4;\n"
            + "\n"
            + "    other_foo_t	    foo_f;"
            + "\n"
            + "endclass\n";

    SVDBFile file = SVDBTestUtils.parse(content, "testClassStringFields");

    SVDBClassDecl foobar = null;
    for (ISVDBItemBase it : file.getChildren()) {
      if (SVDBItem.getName(it).equals("foobar")) {
        foobar = (SVDBClassDecl) it;
        break;
      }
    }

    SVDBTypedefStmt foobar_td = null;
    ISVDBItemBase foobar_i = null;
    ISVDBItemBase foobar_i1 = null;

    for (ISVDBItemBase it : foobar.getChildren()) {
      if (SVDBItem.getName(it).equals("other_foo_t")) {
        foobar_i = it;
      } else if (SVDBItem.getName(it).equals("other_foo_t1")) {
        foobar_i1 = it;
      }
    }

    assertNotNull("Failed to find other_foo_t", foobar_i);
    assertNotNull("Failed to find other_foo_t1", foobar_i1);
    assertEquals("other_foo_t is of wrong type", foobar_i.getType(), SVDBItemType.TypedefStmt);

    foobar_td = (SVDBTypedefStmt) foobar_i;

    assertEquals(
        "other_foo_t type-info is of wrong type",
        SVDBItemType.TypeInfoFwdDecl,
        foobar_td.getTypeInfo().getType());
  }
  public void testTypedef() {
    String content =
        "class foobar;\n"
            + "\n"
            + "    typedef enum {\n"
            + "        FOO,\n"
            + "        BAR\n"
            + "    } foobar_t;\n"
            + "\n"
            + "\n"
            + "    foobar_t     foo_f;"
            + "\n"
            + "endclass\n";

    SVDBFile file = SVDBTestUtils.parse(content, "testClassStringFields");

    SVDBClassDecl foobar = null;
    for (ISVDBItemBase it : file.getChildren()) {
      if (SVDBItem.getName(it).equals("foobar")) {
        foobar = (SVDBClassDecl) it;
        break;
      }
    }

    SVDBTypedefStmt foobar_td = null;
    ISVDBItemBase foobar_i = null;

    for (ISVDBItemBase it : foobar.getChildren()) {
      if (SVDBItem.getName(it).equals("foobar_t")) {
        foobar_i = it;
      }
    }

    assertNotNull("Failed to find foobar_t", foobar_i);
    assertEquals("foobar_t is of wrong type", foobar_i.getType(), SVDBItemType.TypedefStmt);

    foobar_td = (SVDBTypedefStmt) foobar_i;

    assertEquals(
        "foobar_t type-info is of wrong type",
        SVDBItemType.TypeInfoEnum,
        foobar_td.getTypeInfo().getType());

    SVDBTypeInfoEnum enum_t = (SVDBTypeInfoEnum) foobar_td.getTypeInfo();
    assertEquals(
        "foobar_t doesn't have correct number of elements", 2, enum_t.getEnumerators().size());
  }
  public void testClassStringFields() {
    String content =
        "class __sv_builtin_covergroup_options;\n"
            + "int 	weight;\n"
            + "\n"
            + "real 	goal;\n"
            + "\n"
            + "string 	name;\n"
            + "\n"
            + "string 	comment;\n"
            + "\n"
            + "int		at_least;\n"
            + "\n"
            + "bit		detect_overlap;\n"
            + "\n"
            + "int		auto_bin_max;\n"
            + "\n"
            + "bit		per_instance;\n"
            + "\n"
            + "bit		cross_num_print_missing;\n"
            + "\n"
            + "endclass\n";
    LogHandle log = LogFactory.getLogHandle("testClassStringFields");
    SVDBFile file = SVDBTestUtils.parse(content, "testClassStringFields");

    SVDBClassDecl cg_options = null;
    for (ISVDBItemBase it : file.getChildren()) {
      if (SVDBItem.getName(it).equals("__sv_builtin_covergroup_options")) {
        cg_options = (SVDBClassDecl) it;
      }
      log.debug("Item: " + it.getType() + " " + SVDBItem.getName(it));
    }

    assertNotNull("Failed to find class __sv_builtin_covergroup_options", cg_options);

    for (ISVDBItemBase it : cg_options.getChildren()) {
      log.debug("    Item: " + it.getType() + " " + SVDBItem.getName(it));
      assertNotNull("Item " + SVDBItem.getName(it) + " does not have a location", it.getLocation());
      if (SVDBStmt.isType(it, SVDBItemType.VarDeclStmt)) {
        assertNotNull(
            "Field " + SVDBItem.getName(it) + " does not have a type",
            ((SVDBVarDeclStmt) it).getTypeInfo());
      }
    }
  }
  private void runTest(SVParserConfig config, String testname, String doc, String exp_items[]) {
    LogHandle log = LogFactory.getLogHandle(testname);
    List<SVDBMarker> markers = new ArrayList<SVDBMarker>();
    Tuple<SVDBFile, SVDBFile> result =
        SVDBTestUtils.parse(
            log,
            SVLanguageLevel.SystemVerilog,
            config,
            new StringInputStream(doc),
            testname,
            markers);

    SVDBFile file = result.second();

    assertEquals("Unexpected errors", 0, markers.size());

    SVDBTestUtils.assertNoErrWarn(file);
    SVDBTestUtils.assertFileHasElements(file, exp_items);
    LogFactory.removeLogHandle(log);
  }
  public void testClassFunctionLineNumbers() {
    String content =
        "class foobar;\n"
            + // 1
            "    int a;\n"
            + // 2
            "    int b;\n"
            + // 3
            "\n"
            + // 4
            "    function void foobar_f();\n"
            + // 5
            "        a = 5;\n"
            + // 6
            "        b = 6;\n"
            + // 7
            "    endfunction\n"
            + // 8
            "\n"
            + // 9
            "    function void foobar_f2();\n"
            + // 10
            "        a = 4;\n"
            + // 11
            "        b = 12;\n"
            + // 12
            "    endfunction\n"
            + // 13
            "\n"
            + // 14
            "endclass\n"
            + // 15
            "\n"
            + // 16
            "\n" // 17
        ;
    SVDBFile file = SVDBTestUtils.parse(content, "testClassStringFields");

    SVDBClassDecl cls = null;

    assertEquals("Wrong number of file elements", 1, SVDBUtil.getChildrenSize(file));

    cls = (SVDBClassDecl) SVDBUtil.getFirstChildItem(file);

    assertNotNull("Start location not specified", cls.getLocation());
    assertNotNull("End location not specified", cls.getEndLocation());

    assertEquals("Wrong start location", 1, cls.getLocation().getLine());
    assertEquals("Wrong end location", 15, cls.getEndLocation().getLine());

    SVDBTask f1 = null, f2 = null;

    for (ISVDBItemBase it : cls.getChildren()) {
      if (SVDBItem.getName(it).equals("foobar_f")) {
        f1 = (SVDBTask) it;
      }
      if (SVDBItem.getName(it).equals("foobar_f2")) {
        f2 = (SVDBTask) it;
      }
    }

    assertNotNull(f1);
    assertNotNull(f2);
    assertEquals("Wrong foobar_f start location", 5, f1.getLocation().getLine());
    assertEquals("Wrong foobar_f end location", 8, f1.getEndLocation().getLine());

    assertEquals("Wrong foobar_f2 start location", 10, f2.getLocation().getLine());
    assertEquals("Wrong foobar_f2 end location", 13, f2.getEndLocation().getLine());
  }
  private void runTestExpErr(String testname, String doc, String exp_items[]) {
    SVDBFile file = SVDBTestUtils.parse(doc, testname, true);

    SVDBTestUtils.assertFileHasElements(file, exp_items);
  }