blob: 5ecb9e5d4df251e9d5e3b80a8c8b41b1d243c55b [file] [log] [blame]
// Copyright 2017-2020 The Verible Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "verilog/analysis/checkers/proper_parameter_declaration_rule.h"
#include <initializer_list>
#include "common/analysis/linter_test_utils.h"
#include "common/analysis/syntax_tree_linter_test_utils.h"
#include "gtest/gtest.h"
#include "verilog/analysis/verilog_analyzer.h"
#include "verilog/parser/verilog_token_enum.h"
namespace verilog {
namespace analysis {
namespace {
using verible::LintTestCase;
using verible::RunApplyFixCases;
using verible::RunConfiguredLintTestCases;
using verible::RunLintTestCases;
// Tests that ProperParameterDeclarationRule does not report a violation when
// not necessary.
TEST(ProperParameterDeclarationRuleTest, BasicTests) {
const std::initializer_list<LintTestCase> kTestCases = {
{""},
{"package foo; endpackage"},
{"module foo; endmodule"},
{"class foo; endclass"},
};
RunLintTestCases<VerilogAnalyzer, ProperParameterDeclarationRule>(kTestCases);
}
// Tests rejection of package parameters and allow package localparams
TEST(ProperParameterDeclarationRuleTest, RejectPackageParameters) {
const std::initializer_list<LintTestCase> kTestCases = {
{"parameter int Foo = 1;"},
{"package foo; ",
{TK_parameter, "parameter"},
" int Bar = 1; endpackage"},
{"package foo; ",
{TK_parameter, "parameter"},
" int Bar = 1; ",
{TK_parameter, "parameter"},
" int Bar2 = 2; "
"endpackage"},
{"module foo #(parameter int Bar = 1); endmodule"},
{"module foo #(int Bar = 1); endmodule"},
{"class foo #(parameter int Bar = 1); endclass"},
{"module foo #(parameter type Foo); endmodule"},
{"module foo; ", {TK_parameter, "parameter"}, " int Bar = 1; endmodule"},
{"class foo; ", {TK_parameter, "parameter"}, " int Bar = 1; endclass"},
{"package foo; class bar; endclass ",
{TK_parameter, "parameter"},
" int HelloWorld = 1; "
"endpackage"},
{"package foo; class bar; ",
{TK_parameter, "parameter"},
" int HelloWorld = 1; endclass "
"endpackage"},
{"module foo #(parameter int Bar = 1); ",
{TK_parameter, "parameter"},
" int HelloWorld = 1; "
"endmodule"},
{"module foo #(parameter type Foo, parameter int Bar = 1); "
"endmodule"},
{"module foo #(parameter type Bar); ",
{TK_parameter, "parameter"},
" type Bar2; endmodule"},
{"module foo #(parameter type Bar);"
"module innerFoo #("
"parameter type innerBar,",
"localparam int j = 2)();",
{TK_parameter, "parameter"},
" int i = 1;"
"localparam int j = 2;"
"endmodule "
"endmodule"},
};
RunLintTestCases<VerilogAnalyzer, ProperParameterDeclarationRule>(kTestCases);
}
// Tests that the expected number of localparam usage violations are found.
TEST(ProperParameterDeclarationRuleTest, LocalParamTests) {
const std::initializer_list<LintTestCase> kTestCases = {
{"module foo; localparam int Bar = 1; endmodule"},
{"class foo; localparam int Bar = 1; endclass"},
{"module foo; localparam int Bar = 1; localparam int Bar2 = 2; "
"endmodule"},
{"module foo #(localparam int Bar = 1); endmodule"},
{"module foo #(localparam type Bar); endmodule"},
{"class foo #(localparam int Bar = 1); endclass"},
{{TK_localparam, "localparam"},
" int Bar = 1;"}, // localparam defined outside a module or package
{"package foo; localparam int Bar = 1; endpackage"},
{"package foo; class bar; endclass localparam int HelloWorld = 1; "
"endpackage"},
{"package foo; class bar; localparam int HelloWorld = 1; endclass "
"endpackage"},
};
RunConfiguredLintTestCases<VerilogAnalyzer, ProperParameterDeclarationRule>(
kTestCases,
"package_allow_parameter:false;package_allow_localparam:true");
}
// Tests that the expected number of localparam and parameter usage violations
// are found when both are used together.
TEST(ProperParameterDeclarationRuleTest, CombinationParametersTest) {
const std::initializer_list<LintTestCase> kTestCases = {
{"parameter int Foo = 1; ",
{TK_localparam, "localparam"},
" int Bar = 1;"},
{"package foo; ",
{TK_parameter, "parameter"},
" int Bar = 1; ",
"localparam int Bar2 = 2; "
"endpackage"},
{"module foo #(parameter int Bar = 1); localparam int Bar2 = 2; "
"endmodule"},
{"module foo #(parameter type Bar); localparam type Bar2; endmodule"},
{"module foo #(localparam int Bar = 1); ",
{TK_parameter, "parameter"},
" int Bar2 = 2; "
"endmodule"},
{"module foo; ",
{TK_parameter, "parameter"},
" int Bar = 1; localparam int Bar2 = 2; endmodule"},
{"class foo; ",
{TK_parameter, "parameter"},
" int Bar = 1; localparam int Bar2 = 2; endclass"},
{"package foo; class bar; localparam int Bar2 = 2; endclass ",
{TK_parameter, "parameter"},
" int HelloWorld = 1; "
"endpackage"},
{"package foo; ",
"localparam",
" int Bar2 = 2; class bar; endclass ",
{TK_parameter, "parameter"},
" int HelloWorld = 1; "
"endpackage"},
{"parameter int Foo = 1; module bar; localparam int Bar2 = 2; "
"endmodule"},
};
RunConfiguredLintTestCases<VerilogAnalyzer, ProperParameterDeclarationRule>(
kTestCases,
"package_allow_parameter:false;package_allow_localparam:true");
}
// package parameters allowed, package localparam's are rejected
TEST(ProperParameterDeclarationRuleTest, AllowPackageParameters) {
const std::initializer_list<LintTestCase> kTestCases = {
{"parameter int Foo = 1;"},
{"package foo; parameter int Bar = 1; endpackage"},
{"package foo; ",
{TK_localparam, "localparam"},
" int Bar = 1; endpackage"},
{"package foo; parameter int Bar = 1; "
"parameter int Bar2 = 2; "
"endpackage"},
{"module foo #(parameter int Bar = 1); endmodule"},
{"module foo #(int Bar = 1); endmodule"},
{"class foo #(parameter int Bar = 1); endclass"},
{"module foo #(parameter type Foo); endmodule"},
{"module foo; ", {TK_parameter, "parameter"}, " int Bar = 1; endmodule"},
{"class foo; ", {TK_parameter, "parameter"}, " int Bar = 1; endclass"},
{"package foo; class bar; endclass ",
"parameter int HelloWorld = 1; "
"endpackage"},
{"package foo; class bar; ",
{TK_parameter, "parameter"},
" int HelloWorld = 1; endclass "
"endpackage"},
{"module foo #(parameter int Bar = 1); ",
{TK_parameter, "parameter"},
" int HelloWorld = 1; "
"endmodule"},
{"module foo #(parameter type Foo, parameter int Bar = 1); "
"endmodule"},
{"module foo #(parameter type Bar); ",
{TK_parameter, "parameter"},
" type Bar2; endmodule"},
{"module foo #(parameter type Bar);"
"module innerFoo #("
"parameter type innerBar,",
"localparam int j = 2)();",
{TK_parameter, "parameter"},
" int i = 1;"
"localparam int j = 2;"
"endmodule "
"endmodule"},
{"module foo; localparam int Bar = 1; endmodule"},
{"class foo; localparam int Bar = 1; endclass"},
{"module foo; localparam int Bar = 1; localparam int Bar2 = 2; "
"endmodule"},
{"module foo #(localparam int Bar = 1); endmodule"},
{"module foo #(localparam type Bar); endmodule"},
{"class foo #(localparam int Bar = 1); endclass"},
{{TK_localparam, "localparam"}, " int Bar = 1;"},
{"package foo; ",
{TK_localparam, "localparam"},
" int Bar = 1; endpackage"},
{"package foo; class bar; endclass ",
{TK_localparam, "localparam"},
" int HelloWorld = 1; "
"endpackage"},
{"package foo; class bar; localparam int HelloWorld = 1; endclass "
"endpackage"},
};
RunConfiguredLintTestCases<VerilogAnalyzer, ProperParameterDeclarationRule>(
kTestCases,
"package_allow_parameter:true;package_allow_localparam:false");
}
TEST(ProperParameterDeclarationRuleTest, AutoFixAllowLocalParamInPackage) {
const std::initializer_list<verible::AutoFixInOut> kTestCases = {
{"package foo; parameter int Bar = 1; endpackage",
"package foo; localparam int Bar = 1; endpackage"},
// TODO (sconwayaus): Commented out as the linter_test_util dosn't handle
// multiple violations. linter_test_utils.h:137] Check failed:
// violations.size() == 1 (2 vs. 1) TODO: apply multi-violation fixes
// {"package foo; parameter int Bar = 1; parameter int Bar2 = 2; "
// "endpackage",
// "package foo; localparam int Bar = 1; localparam int Bar2 = 2; "
// "endpackage"},
{"module foo; parameter int Bar = 1; endmodule",
"module foo; localparam int Bar = 1; endmodule"},
{"class foo; parameter int Bar = 1; endclass",
"class foo; localparam int Bar = 1; endclass"},
{"package foo; class bar; endclass parameter int HelloWorld = 1; "
"endpackage",
"package foo; class bar; endclass localparam int HelloWorld = 1; "
"endpackage"},
{"package foo; class bar; parameter int HelloWorld = 1; endclass "
"endpackage",
"package foo; class bar; localparam int HelloWorld = 1; endclass "
"endpackage"},
{"module foo #(parameter int Bar = 1); parameter int HelloWorld = 1; "
"endmodule",
"module foo #(parameter int Bar = 1); localparam int HelloWorld = 1; "
"endmodule"},
{"module foo #(parameter type Bar); parameter type Bar2; endmodule",
"module foo #(parameter type Bar); localparam type Bar2; endmodule"},
{"module foo #(parameter type Bar);module innerFoo #(parameter type "
"innerBar, localparam int j = 2)();parameter int i = 1; localparam int "
"j = 2; endmodule endmodule",
"module foo #(parameter type Bar);module innerFoo #(parameter type "
"innerBar, localparam int j = 2)();localparam int i = 1; localparam int "
"j = 2; endmodule endmodule"},
};
RunApplyFixCases<VerilogAnalyzer, ProperParameterDeclarationRule>(kTestCases);
}
TEST(ProperParameterDeclarationRuleTest, AutoFixAllowParametersInPackage) {
const std::initializer_list<verible::AutoFixInOut> kTestCases = {
{"package foo; localparam int Bar = 1; endpackage",
"package foo; parameter int Bar = 1; endpackage"},
{"module foo; parameter int Bar = 1; endmodule",
"module foo; localparam int Bar = 1; endmodule"},
{"class foo; parameter int Bar = 1; endclass",
"class foo; localparam int Bar = 1; endclass"},
{"package foo; class bar; parameter int HelloWorld = 1; endclass "
"endpackage",
"package foo; class bar; localparam int HelloWorld = 1; endclass "
"endpackage"},
{"module foo #(parameter int Bar = 1); parameter int HelloWorld = 1; "
"endmodule",
"module foo #(parameter int Bar = 1); localparam int HelloWorld = 1; "
"endmodule"},
{"module foo #(parameter type Bar); parameter type Bar2; endmodule",
"module foo #(parameter type Bar); localparam type Bar2; endmodule"},
{"module foo #(parameter type Bar);"
"module innerFoo #("
"parameter type innerBar, localparam int j = 2)();parameter int i = 1;"
"localparam int j = 2;"
"endmodule "
"endmodule",
"module foo #(parameter type Bar);"
"module innerFoo #("
"parameter type innerBar, localparam int j = 2)();localparam int i = 1;"
"localparam int j = 2;"
"endmodule "
"endmodule"},
{"localparam int Bar = 1;", "parameter int Bar = 1;"},
{"package foo; localparam int Bar = 1; endpackage",
"package foo; parameter int Bar = 1; endpackage"},
{"package foo; class bar; endclass localparam int HelloWorld = 1; "
"endpackage",
"package foo; class bar; endclass parameter int HelloWorld = 1; "
"endpackage"},
};
RunApplyFixCases<VerilogAnalyzer, ProperParameterDeclarationRule>(
kTestCases,
"package_allow_parameter:true;package_allow_localparam:false");
}
} // namespace
} // namespace analysis
} // namespace verilog