-
Notifications
You must be signed in to change notification settings - Fork 559
Don't suggest an export if it's a modularity error to use that package #8835
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
3819409
1bc635a
4c21346
f1a0eb8
f502624
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,13 +4,9 @@ | |
#include "absl/synchronization/blocking_counter.h" | ||
#include "ast/treemap/treemap.h" | ||
#include "common/concurrency/ConcurrentQueue.h" | ||
#include "common/sort/sort.h" | ||
#include "common/strings/formatting.h" | ||
#include "core/Context.h" | ||
#include "core/errors/packager.h" | ||
#include "core/errors/resolver.h" | ||
#include <algorithm> | ||
#include <iterator> | ||
|
||
using namespace std; | ||
|
||
|
@@ -407,46 +403,14 @@ class VisibilityCheckerPass final { | |
} else if (litSymbol.isFieldOrStaticField()) { | ||
isExported = litSymbol.asFieldRef().data(ctx)->flags.isExported; | ||
} | ||
|
||
// Did we use a constant that wasn't exported? | ||
if (!isExported && !db.allowRelaxedPackagerChecksFor(this->package.mangledName())) { | ||
if (auto e = ctx.beginError(lit.loc(), core::errors::Packager::UsedPackagePrivateName)) { | ||
auto &pkg = ctx.state.packageDB().getPackageInfo(otherPackage); | ||
e.setHeader("`{}` resolves but is not exported from `{}`", litSymbol.show(ctx), pkg.show(ctx)); | ||
auto definedHereLoc = litSymbol.loc(ctx); | ||
if (definedHereLoc.file().data(ctx).isRBI()) { | ||
e.addErrorSection(core::ErrorSection( | ||
core::ErrorColors::format( | ||
"Consider marking this RBI file `{}` if it is meant to declare unpackaged constants", | ||
"# packaged: false"), | ||
{core::ErrorLine(definedHereLoc, "")})); | ||
} else { | ||
e.addErrorLine(definedHereLoc, "Defined here"); | ||
} | ||
|
||
auto symToExport = litSymbol; | ||
auto enumClass = getEnumClassForEnumValue(ctx.state, symToExport); | ||
if (enumClass.exists()) { | ||
symToExport = enumClass; | ||
} | ||
if (auto exp = pkg.addExport(ctx, symToExport)) { | ||
e.addAutocorrect(std::move(exp.value())); | ||
} | ||
if (!db.errorHint().empty()) { | ||
e.addErrorNote("{}", db.errorHint()); | ||
} | ||
} | ||
|
||
return; | ||
} | ||
|
||
auto importType = this->package.importsPackage(otherPackage); | ||
auto wasNotImported = !importType.has_value(); | ||
isExported = isExported || db.allowRelaxedPackagerChecksFor(this->package.mangledName()); | ||
auto currentImportType = this->package.importsPackage(otherPackage); | ||
auto wasImported = currentImportType.has_value(); | ||
auto importedAsTest = | ||
importType.has_value() && importType.value() == core::packages::ImportType::Test && !this->insideTestFile; | ||
if (wasNotImported || importedAsTest) { | ||
wasImported && currentImportType.value() == core::packages::ImportType::Test && !this->insideTestFile; | ||
if (!wasImported || importedAsTest || !isExported) { | ||
auto &pkg = ctx.state.packageDB().getPackageInfo(otherPackage); | ||
bool isTestImport = otherFile.data(ctx).isPackagedTest() || ctx.file.data(ctx).isPackagedTest(); | ||
bool isTestImport = otherFile.data(ctx).isPackagedTest() || this->insideTestFile; | ||
auto strictDepsLevel = this->package.strictDependenciesLevel(); | ||
auto importStrictDepsLevel = pkg.strictDependenciesLevel(); | ||
bool layeringViolation = false; | ||
|
@@ -468,8 +432,34 @@ class VisibilityCheckerPass final { | |
path.has_value(); | ||
} | ||
if (!causesCycle && !layeringViolation && !strictDependenciesTooLow) { | ||
if (wasNotImported) { | ||
// We failed to import the package that defines the symbol | ||
if (!isExported) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here, |
||
if (auto e = ctx.beginError(lit.loc(), core::errors::Packager::UsedPackagePrivateName)) { | ||
auto &pkg = ctx.state.packageDB().getPackageInfo(otherPackage); | ||
e.setHeader("`{}` resolves but is not exported from `{}`", litSymbol.show(ctx), pkg.show(ctx)); | ||
auto definedHereLoc = litSymbol.loc(ctx); | ||
if (definedHereLoc.file().data(ctx).isRBI()) { | ||
e.addErrorSection(core::ErrorSection( | ||
core::ErrorColors::format("Consider marking this RBI file `{}` if it is meant to " | ||
"declare unpackaged constants", | ||
"# packaged: false"), | ||
{core::ErrorLine(definedHereLoc, "")})); | ||
} else { | ||
e.addErrorLine(definedHereLoc, "Defined here"); | ||
} | ||
|
||
auto symToExport = litSymbol; | ||
auto enumClass = getEnumClassForEnumValue(ctx.state, symToExport); | ||
if (enumClass.exists()) { | ||
symToExport = enumClass; | ||
} | ||
if (auto exp = pkg.addExport(ctx, symToExport)) { | ||
e.addAutocorrect(std::move(exp.value())); | ||
} | ||
if (!db.errorHint().empty()) { | ||
e.addErrorNote("{}", db.errorHint()); | ||
} | ||
} | ||
} else if (!wasImported) { | ||
if (auto e = ctx.beginError(lit.loc(), core::errors::Packager::MissingImport)) { | ||
e.setHeader("`{}` resolves but its package is not imported", lit.symbol().show(ctx)); | ||
e.addErrorLine(pkg.declLoc(), "Exported from package here"); | ||
|
@@ -487,13 +477,17 @@ class VisibilityCheckerPass final { | |
} | ||
} | ||
} else if (importedAsTest) { | ||
ENFORCE(!isTestImport); | ||
if (auto e = ctx.beginError(lit.loc(), core::errors::Packager::UsedTestOnlyName)) { | ||
e.setHeader("Used `{}` constant `{}` in non-test file", "test_import", litSymbol.show(ctx)); | ||
e.addErrorLine(pkg.declLoc(), "Defined here"); | ||
auto &pkg = ctx.state.packageDB().getPackageInfo(otherPackage); | ||
if (auto exp = this->package.addImport(ctx, pkg, false)) { | ||
e.addAutocorrect(std::move(exp.value())); | ||
if (!db.errorHint().empty()) { | ||
e.addErrorNote("{}", db.errorHint()); | ||
} | ||
Comment on lines
+487
to
+489
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We typically put the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, moved the |
||
} | ||
e.addErrorLine(pkg.declLoc(), "Defined here"); | ||
} | ||
} else { | ||
ENFORCE(false); | ||
|
@@ -563,7 +557,9 @@ class VisibilityCheckerPass final { | |
ENFORCE(false, "At most three reasons should be present"); | ||
} | ||
e.setHeader("`{}` cannot be referenced here because {}", lit.symbol().show(ctx), reason); | ||
if (wasNotImported) { | ||
if (!isExported) { | ||
e.addErrorNote("`{}` is not exported", lit.symbol().show(ctx)); | ||
} else if (!wasImported) { | ||
e.addErrorNote("`{}`'s package is not imported", lit.symbol().show(ctx)); | ||
} else if (importedAsTest) { | ||
e.addErrorNote("`{}`'s package is imported as `{}`", lit.symbol().show(ctx), "test_import"); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# frozen_string_literal: true | ||
# typed: strict | ||
# enable-packager: true | ||
|
||
class Foo::Bar::AppFalseCyclePackage < PackageSpec | ||
layer 'app' | ||
strict_dependencies 'false' | ||
|
||
import Foo::Bar::AppFalseCyclePackage::SubPackage | ||
import Foo::MyPackage | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# typed: strict | ||
|
||
class Foo::Bar::AppFalseCyclePackage::OtherClass | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# frozen_string_literal: true | ||
# typed: strict | ||
# enable-packager: true | ||
|
||
|
||
class Foo::Bar::AppFalseCyclePackage::SubPackage < PackageSpec | ||
layer 'lib' | ||
strict_dependencies 'false' | ||
|
||
import Foo::Bar::AppFalseCyclePackage | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# frozen_string_literal: true | ||
# typed: strict | ||
# enable-packager: true | ||
|
||
class Foo::MyPackage < PackageSpec | ||
layer 'lib' | ||
strict_dependencies 'layered_dag' | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# typed: strict | ||
|
||
module Foo | ||
module MyPackage | ||
class FooClass | ||
Foo::Bar::AppFalseCyclePackage::OtherClass | ||
end | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ooc, were these includes in service of assorted rbi-gen stuff? or do you think they became unused before we deleted the rbi-gen stuff?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably before the rbi-gen stuff. For example, this commit got rid of the call to
fast_sort
. I assume something similar for the otherinclude
s.