From b780d557e736dc17f9e4f0dee24d3786df0fbc4d Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Wed, 31 Aug 2022 19:45:07 +0800 Subject: [PATCH 01/19] test: Add test with slightly wrong output for structs. --- test/scip/testdata/struct.rb | 28 +++++++ test/scip/testdata/struct.snapshot.rb | 116 ++++++++++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 test/scip/testdata/struct.rb create mode 100644 test/scip/testdata/struct.snapshot.rb diff --git a/test/scip/testdata/struct.rb b/test/scip/testdata/struct.rb new file mode 100644 index 000000000..492ea1fac --- /dev/null +++ b/test/scip/testdata/struct.rb @@ -0,0 +1,28 @@ +# typed: true + +# From Sorbet docs https://sorbet.org/docs/tstruct +class S < T::Struct + prop :prop_i, Integer + const :const_s, T.nilable(String) + const :const_f, Float, default: 0.5 +end + +def f + s = S.new(prop_i: 3) + _ = s.prop_i.to_s + s.const_s + s.const_f.to_s + s.serialize.to_s + s.prop_i = 4 + return +end + +POINT = Struct.new(:x, :y) do + def array + [x, y] + end +end + +def g + p = POINT.new(0, 1) + a = p.array + px = p.x + return +end diff --git a/test/scip/testdata/struct.snapshot.rb b/test/scip/testdata/struct.snapshot.rb new file mode 100644 index 000000000..3465473e9 --- /dev/null +++ b/test/scip/testdata/struct.snapshot.rb @@ -0,0 +1,116 @@ + # typed: true + + # From Sorbet docs https://sorbet.org/docs/tstruct + class S < T::Struct +# ^ definition [..] S# +# ^ reference [..] T# +# ^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). +# ^^^^^^ reference [..] Sorbet#Private#``#sig(). +# ^^^^^^ reference [..] Sorbet#Private#Static# +# ^^^^^^ definition [..] S#initialize(). +# ^^^^^^ definition [..] T#Struct# +# ^^^^^^ reference [..] T#Private#Methods#DeclBuilder#void(). + prop :prop_i, Integer +# ^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# +# ^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). +# ^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). +# ^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). +# ^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). +# ^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). +# ^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# +# ^^^^^^^^^^^^^^^^^^^^^ definition [..] S#`prop_i=`(). +# ^^^^^^^^^^^^^^^^^^^^^ definition [..] S#prop_i(). +# ^^^^^^^ reference [..] Integer# +# ^^^^^^^ reference [..] Integer# +# ^^^^^^^ reference [..] Integer# +# ^^^^^^^ reference [..] Integer# +# ^^^^^^^ reference [..] Integer# + const :const_s, T.nilable(String) +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] S#const_s(). +# ^ reference [..] T# +# ^ reference [..] T# +# ^ reference [..] T# +# ^^^^^^^ reference [..] ``#nilable(). +# ^^^^^^^ reference [..] ``#nilable(). +# ^^^^^^^ reference [..] ``#nilable(). +# ^^^^^^ reference [..] String# +# ^^^^^^ reference [..] String# +# ^^^^^^ reference [..] String# + const :const_f, Float, default: 0.5 +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] S#const_f(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# +# ^^^^^ reference [..] Float# +# ^^^^^ reference [..] Float# +# ^^^^^ reference [..] Float# + end + + def f +#^^^^^ definition [..] Object#f(). + s = S.new(prop_i: 3) +# ^ definition local 1~#3809224601 +# ^ reference [..] S# + _ = s.prop_i.to_s + s.const_s + s.const_f.to_s + s.serialize.to_s +# ^ definition local 3~#3809224601 +# ^ reference local 1~#3809224601 +# ^^^^^^ reference [..] S#prop_i(). +# ^^^^ reference [..] Integer#to_s(). +# ^ reference [..] String#+(). +# ^ reference local 1~#3809224601 +# ^^^^^^^ reference [..] S#const_s(). +# ^ reference [..] String#+(). +# ^ reference local 1~#3809224601 +# ^^^^^^^ reference [..] S#const_f(). +# ^^^^ reference [..] Float#to_s(). +# ^ reference [..] String#+(). +# ^ reference local 1~#3809224601 + s.prop_i = 4 +# ^ reference local 1~#3809224601 +# ^^^^^^^^ reference [..] S#`prop_i=`(). + return + end + + POINT = Struct.new(:x, :y) do +#^^^^^ definition [..] POINT# +#^^^^^^^^^^^^^^^^^^^^ definition [..] Struct# +#^^^^^^^^^^^^^^^^^^^^ definition [..] POINT#initialize(). +#^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). +#^^^^^^^^^^^^^^^^^^^^ reference [..] T# +#^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#void(). +#^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). +#^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). +#^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# +#^^^^^^^^^^^^^^^^^^^^ definition local 5~#119448696 +# ^ definition [..] POINT#x(). +# ^ definition [..] POINT#`x=`(). +# ^ reference [..] BasicObject# +# ^ definition [..] POINT#y(). +# ^ definition [..] POINT#`y=`(). +# ^ reference [..] BasicObject# + def array +# ^^^^^^^^^ definition [..] POINT#array(). + [x, y] +# ^ reference [..] POINT#x(). +# ^ reference [..] POINT#y(). + end + end + + def g +#^^^^^ definition [..] Object#g(). + p = POINT.new(0, 1) +# ^ definition local 1~#3792446982 +# ^^^^^ reference [..] POINT# + a = p.array +# ^ definition local 3~#3792446982 +# ^ reference local 1~#3792446982 +# ^^^^^ reference [..] POINT#array(). + px = p.x +# ^^ definition local 4~#3792446982 +# ^ reference local 1~#3792446982 +# ^ reference [..] POINT#x(). + return + end From bccfec4d7cb27d5e2ac9150ff58e83774bfe0861 Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Mon, 5 Sep 2022 12:04:18 +0800 Subject: [PATCH 02/19] fix: Propagate method name source locations. --- ast/Helpers.h | 25 +- ast/TreeCopying.cc | 2 +- ast/Trees.cc | 7 +- ast/Trees.h | 9 +- ast/desugar/Desugar.cc | 15 +- cfg/CFG.cc | 33 ++- class_flatten/class_flatten.cc | 7 +- core/FoundDefinitions.h | 3 +- core/GlobalState.cc | 21 +- core/GlobalState.h | 2 +- core/Symbols.cc | 5 +- core/Symbols.h | 3 +- core/serialize/serialize.cc | 4 +- namer/namer.cc | 10 +- parser/Builder.cc | 22 +- parser/tools/generate_ast.cc | 7 +- resolver/resolver.cc | 8 +- rewriter/AttrReader.cc | 5 +- rewriter/Command.cc | 2 +- rewriter/DSLBuilder.cc | 11 +- rewriter/DefDelegator.cc | 2 +- rewriter/Delegate.cc | 3 +- rewriter/Flatfiles.cc | 5 +- rewriter/Mattr.cc | 6 +- rewriter/Minitest.cc | 9 +- rewriter/MixinEncryptedProp.cc | 4 +- rewriter/ModuleFunction.cc | 2 +- rewriter/Prop.cc | 28 ++- rewriter/Singleton.cc | 4 +- rewriter/Struct.cc | 10 +- rewriter/TestCase.cc | 4 +- rewriter/Util.cc | 11 +- rewriter/Util.h | 5 +- scip_indexer/SCIPIndexer.cc | 23 +- test/hello-test.cc | 2 +- test/scip/testdata/args.snapshot.rb | 6 +- test/scip/testdata/arrays.snapshot.rb | 2 +- test/scip/testdata/classes.snapshot.rb | 16 +- test/scip/testdata/def_delegator.snapshot.rb | 16 +- .../testdata/fields_and_attrs.snapshot.rb | 30 +-- test/scip/testdata/for.snapshot.rb | 2 +- test/scip/testdata/functions.snapshot.rb | 4 +- test/scip/testdata/gem_metadata.snapshot.rb | 4 +- test/scip/testdata/hashes.snapshot.rb | 2 +- test/scip/testdata/hoverdocs.snapshot.rb | 226 +++++++++--------- .../testdata/implicit_super_arg.snapshot.rb | 2 +- test/scip/testdata/inheritance.snapshot.rb | 12 +- .../loops_and_conditionals.snapshot.rb | 14 +- .../multifile/basic/def_class1.snapshot.rb | 2 +- test/scip/testdata/rescue.snapshot.rb | 4 +- test/scip/testdata/struct.snapshot.rb | 14 +- test/scip/testdata/type_change.snapshot.rb | 60 ++--- test/scip/testdata/type_docs.snapshot.rb | 12 +- test/scip/testdata/types.snapshot.rb | 6 +- 54 files changed, 413 insertions(+), 340 deletions(-) diff --git a/ast/Helpers.h b/ast/Helpers.h index a67df9e95..b46f4ad62 100644 --- a/ast/Helpers.h +++ b/ast/Helpers.h @@ -244,36 +244,37 @@ class MK { core::make_type(core::Symbols::String(), value)); } - static ExpressionPtr Method(core::LocOffsets loc, core::LocOffsets declLoc, core::NameRef name, - MethodDef::ARGS_store args, ExpressionPtr rhs, + static ExpressionPtr Method(core::LocOffsets loc, core::LocOffsets declLoc, core::LocOffsets nameLoc, + core::NameRef name, MethodDef::ARGS_store args, ExpressionPtr rhs, MethodDef::Flags flags = MethodDef::Flags()) { if (args.empty() || (!isa_tree(args.back()) && !isa_tree(args.back()))) { auto blkLoc = core::LocOffsets::none(); args.emplace_back(make_expression(blkLoc, MK::Local(blkLoc, core::Names::blkArg()))); } - return make_expression(loc, declLoc, core::Symbols::todoMethod(), name, std::move(args), + return make_expression(loc, declLoc, nameLoc, core::Symbols::todoMethod(), name, std::move(args), std::move(rhs), flags); } - static ExpressionPtr SyntheticMethod(core::LocOffsets loc, core::LocOffsets declLoc, core::NameRef name, - MethodDef::ARGS_store args, ExpressionPtr rhs, + static ExpressionPtr SyntheticMethod(core::LocOffsets loc, core::LocOffsets declLoc, core::LocOffsets nameLoc, + core::NameRef name, MethodDef::ARGS_store args, ExpressionPtr rhs, MethodDef::Flags flags = MethodDef::Flags()) { flags.isRewriterSynthesized = true; - return Method(loc, declLoc, name, std::move(args), std::move(rhs), flags); + return Method(loc, declLoc, nameLoc, name, std::move(args), std::move(rhs), flags); } - static ExpressionPtr SyntheticMethod0(core::LocOffsets loc, core::LocOffsets declLoc, core::NameRef name, - ExpressionPtr rhs, MethodDef::Flags flags = MethodDef::Flags()) { + static ExpressionPtr SyntheticMethod0(core::LocOffsets loc, core::LocOffsets declLoc, core::LocOffsets nameLoc, + core::NameRef name, ExpressionPtr rhs, + MethodDef::Flags flags = MethodDef::Flags()) { MethodDef::ARGS_store args; - return SyntheticMethod(loc, declLoc, name, std::move(args), std::move(rhs), flags); + return SyntheticMethod(loc, declLoc, nameLoc, name, std::move(args), std::move(rhs), flags); } - static ExpressionPtr SyntheticMethod1(core::LocOffsets loc, core::LocOffsets declLoc, core::NameRef name, - ExpressionPtr arg0, ExpressionPtr rhs, + static ExpressionPtr SyntheticMethod1(core::LocOffsets loc, core::LocOffsets declLoc, core::LocOffsets nameLoc, + core::NameRef name, ExpressionPtr arg0, ExpressionPtr rhs, MethodDef::Flags flags = MethodDef::Flags()) { MethodDef::ARGS_store args; args.emplace_back(std::move(arg0)); - return SyntheticMethod(loc, declLoc, name, std::move(args), std::move(rhs), flags); + return SyntheticMethod(loc, declLoc, nameLoc, name, std::move(args), std::move(rhs), flags); } static ExpressionPtr ClassOrModule(core::LocOffsets loc, core::LocOffsets declLoc, ExpressionPtr name, diff --git a/ast/TreeCopying.cc b/ast/TreeCopying.cc index 35d410287..8f7484721 100644 --- a/ast/TreeCopying.cc +++ b/ast/TreeCopying.cc @@ -44,7 +44,7 @@ ExpressionPtr deepCopy(const void *avoid, const Tag tag, const void *tree, bool case Tag::MethodDef: { auto *exp = reinterpret_cast(tree); - return make_expression(exp->loc, exp->declLoc, exp->symbol, exp->name, + return make_expression(exp->loc, exp->declLoc, exp->nameLoc, exp->symbol, exp->name, deepCopyVec(avoid, exp->args), deepCopy(avoid, exp->rhs), exp->flags); } diff --git a/ast/Trees.cc b/ast/Trees.cc index ae2fe1267..8eae791d6 100644 --- a/ast/Trees.cc +++ b/ast/Trees.cc @@ -164,9 +164,10 @@ ClassDef::ClassDef(core::LocOffsets loc, core::LocOffsets declLoc, core::ClassOr _sanityCheck(); } -MethodDef::MethodDef(core::LocOffsets loc, core::LocOffsets declLoc, core::MethodRef symbol, core::NameRef name, - ARGS_store args, ExpressionPtr rhs, Flags flags) - : loc(loc), declLoc(declLoc), symbol(symbol), rhs(std::move(rhs)), args(std::move(args)), name(name), flags(flags) { +MethodDef::MethodDef(core::LocOffsets loc, core::LocOffsets declLoc, core::LocOffsets nameLoc, core::MethodRef symbol, + core::NameRef name, ARGS_store args, ExpressionPtr rhs, Flags flags) + : loc(loc), declLoc(declLoc), nameLoc(nameLoc), symbol(symbol), rhs(std::move(rhs)), args(std::move(args)), + name(name), flags(flags) { categoryCounterInc("trees", "methoddef"); histogramInc("trees.methodDef.args", this->args.size()); _sanityCheck(); diff --git a/ast/Trees.h b/ast/Trees.h index 738b9ecc7..bce8bcaba 100644 --- a/ast/Trees.h +++ b/ast/Trees.h @@ -388,6 +388,9 @@ EXPRESSION(MethodDef) { /// The range for the method declaration, including 'def' and ending /// after the closing ')' after the parameter list. core::LocOffsets declLoc; + /// The range for the name of the method itself in the method declaration, + /// excluding 'def' and the parameter list '(...)'. + core::LocOffsets nameLoc; /// Reference to the method data. core::MethodRef symbol; @@ -401,8 +404,8 @@ EXPRESSION(MethodDef) { using Flags = core::FoundMethod::Flags; Flags flags; - MethodDef(core::LocOffsets loc, core::LocOffsets declLoc, core::MethodRef symbol, core::NameRef name, - ARGS_store args, ExpressionPtr rhs, Flags flags); + MethodDef(core::LocOffsets loc, core::LocOffsets declLoc, core::LocOffsets nameLoc, core::MethodRef symbol, + core::NameRef name, ARGS_store args, ExpressionPtr rhs, Flags flags); ExpressionPtr deepCopy() const; @@ -412,7 +415,7 @@ EXPRESSION(MethodDef) { void _sanityCheck(); }; -CheckSize(MethodDef, 64, 8); +CheckSize(MethodDef, 72, 8); EXPRESSION(If) { public: diff --git a/ast/desugar/Desugar.cc b/ast/desugar/Desugar.cc index 27401c9dd..065692069 100644 --- a/ast/desugar/Desugar.cc +++ b/ast/desugar/Desugar.cc @@ -300,8 +300,9 @@ ExpressionPtr validateRBIBody(DesugarContext dctx, ExpressionPtr body) { return body; } -ExpressionPtr buildMethod(DesugarContext dctx, core::LocOffsets loc, core::LocOffsets declLoc, core::NameRef name, - unique_ptr &argnode, unique_ptr &body, bool isSelf) { +ExpressionPtr buildMethod(DesugarContext dctx, core::LocOffsets loc, core::LocOffsets declLoc, core::LocOffsets nameLoc, + core::NameRef name, unique_ptr &argnode, unique_ptr &body, + bool isSelf) { // Reset uniqueCounter within this scope (to keep numbers small) uint32_t uniqueCounter = 1; DesugarContext dctx1(dctx.ctx, uniqueCounter, dctx.enclosingBlockArg, declLoc, name); @@ -320,7 +321,7 @@ ExpressionPtr buildMethod(DesugarContext dctx, core::LocOffsets loc, core::LocOf ExpressionPtr desugaredBody = desugarBody(dctx2, loc, body, std::move(destructures)); desugaredBody = validateRBIBody(dctx2, move(desugaredBody)); - auto mdef = MK::Method(loc, declLoc, name, std::move(args), std::move(desugaredBody)); + auto mdef = MK::Method(loc, declLoc, nameLoc, name, std::move(args), std::move(desugaredBody)); cast_tree(mdef)->flags.isSelfMethod = isSelf; return mdef; } @@ -1515,8 +1516,8 @@ ExpressionPtr node2TreeImpl(DesugarContext dctx, unique_ptr what) }, [&](parser::DefMethod *method) { bool isSelf = false; - ExpressionPtr res = - buildMethod(dctx, method->loc, method->declLoc, method->name, method->args, method->body, isSelf); + ExpressionPtr res = buildMethod(dctx, method->loc, method->declLoc, method->nameLoc, method->name, + method->args, method->body, isSelf); result = std::move(res); }, [&](parser::DefS *method) { @@ -1528,8 +1529,8 @@ ExpressionPtr node2TreeImpl(DesugarContext dctx, unique_ptr what) } } bool isSelf = true; - ExpressionPtr res = - buildMethod(dctx, method->loc, method->declLoc, method->name, method->args, method->body, isSelf); + ExpressionPtr res = buildMethod(dctx, method->loc, method->declLoc, method->nameLoc, method->name, + method->args, method->body, isSelf); result = std::move(res); }, [&](parser::SClass *sclass) { diff --git a/cfg/CFG.cc b/cfg/CFG.cc index 7027acb1f..621da7df1 100644 --- a/cfg/CFG.cc +++ b/cfg/CFG.cc @@ -238,10 +238,30 @@ string CFG::toString(const core::GlobalState &gs) const { return to_string(buf); } +string locToString(const core::GlobalState &gs, core::Loc loc) { + if (!loc.exists() || loc.empty()) { + return " @ <>"; + } + auto [start, end] = loc.position(gs); + return start.line == end.line ? fmt::format(" @ {}:{}-{}", start.line, start.column, end.column) + : fmt::format(" @ {}:{}-{}:{}", start.line, start.column, end.line, end.column); +} + string CFG::toTextualString(const core::GlobalState &gs, optional file) const { fmt::memory_buffer buf; string symbolName = this->symbol.showFullName(gs); - fmt::format_to(std::back_inserter(buf), "method {} {{\n\n", symbolName); + if (file) { + auto method = this->symbol.data(gs); + if (method->nameLoc.exists() && !method->nameLoc.empty()) { + fmt::format_to(std::back_inserter(buf), "method{} {} {{\n\n", + locToString(gs, core::Loc(file.value(), method->nameLoc)), symbolName); + } else { + fmt::format_to(std::back_inserter(buf), "method{} (full) {} {{\n\n", locToString(gs, method->loc()), + symbolName); + } + } else { + fmt::format_to(std::back_inserter(buf), "method {} {{\n\n", symbolName); + } for (auto &basicBlock : this->basicBlocks) { if (!basicBlock->backEdges.empty()) { fmt::format_to(std::back_inserter(buf), "# backedges\n"); @@ -379,16 +399,7 @@ string BasicBlock::toTextualString(const core::GlobalState &gs, optionalexprs) { string positionText = ""; if (file) { - if (exp.loc.exists() && !exp.loc.empty()) { - auto lineCol = core::Loc(file.value(), exp.loc).position(gs); - positionText = - lineCol.first.line == lineCol.second.line - ? fmt::format(" @ {}:{}-{}", lineCol.first.line, lineCol.first.column, lineCol.second.column) - : fmt::format(" @ {}:{}-{}:{}", lineCol.first.line, lineCol.first.column, lineCol.second.line, - lineCol.second.column); - } else { - positionText = " @ <>"; - } + positionText = locToString(gs, core::Loc(file.value(), exp.loc)); } fmt::format_to(std::back_inserter(buf), " {}{} = {}\n", exp.bind.toString(gs, cfg), positionText, diff --git a/class_flatten/class_flatten.cc b/class_flatten/class_flatten.cc index 0e9dbe291..ff1d17b0c 100644 --- a/class_flatten/class_flatten.cc +++ b/class_flatten/class_flatten.cc @@ -111,9 +111,10 @@ class ClassFlattenWalk { ast::MethodDef::ARGS_store args; args.emplace_back(ast::make_expression(blkLoc, blkLocalVar)); - auto init = - ast::make_expression(classDef->declLoc, classDef->declLoc, sym, core::Names::staticInit(), - std::move(args), std::move(inits), ast::MethodDef::Flags()); + // TODO(varun): What does classDef->declLoc correspond to? + auto init = ast::make_expression(classDef->declLoc, classDef->declLoc, classDef->declLoc, sym, + core::Names::staticInit(), std::move(args), std::move(inits), + ast::MethodDef::Flags()); ast::cast_tree_nonnull(init).flags.isRewriterSynthesized = false; ast::cast_tree_nonnull(init).flags.isSelfMethod = true; diff --git a/core/FoundDefinitions.h b/core/FoundDefinitions.h index 5a3ba2c41..e73f7f445 100644 --- a/core/FoundDefinitions.h +++ b/core/FoundDefinitions.h @@ -142,6 +142,7 @@ struct FoundMethod final { core::NameRef name; core::LocOffsets loc; core::LocOffsets declLoc; + core::LocOffsets nameLoc; std::vector parsedArgs; core::ArityHash arityHash; struct Flags { @@ -161,7 +162,7 @@ struct FoundMethod final { std::string toString(const core::GlobalState &gs, const FoundDefinitions &foundDefs, uint32_t id) const; }; -CheckSize(FoundMethod, 56, 8); +CheckSize(FoundMethod, 64, 8); struct FoundModifier { enum class Kind : uint8_t { diff --git a/core/GlobalState.cc b/core/GlobalState.cc index de181662a..a11b7daee 100644 --- a/core/GlobalState.cc +++ b/core/GlobalState.cc @@ -127,7 +127,7 @@ struct MethodBuilder { }; MethodBuilder enterMethod(GlobalState &gs, ClassOrModuleRef klass, NameRef name) { - return MethodBuilder{gs, gs.enterMethodSymbol(Loc::none(), klass, name)}; + return MethodBuilder{gs, gs.enterMethodSymbol(Loc::none(), klass, name, LocOffsets::none())}; } struct ParentLinearizationInformation { @@ -303,7 +303,8 @@ void GlobalState::initEmpty() { ClassOrModuleRef klass; klass = synthesizeClass(core::Names::Constants::NoSymbol(), 0); ENFORCE(klass == Symbols::noClassOrModule()); - MethodRef method = enterMethodSymbol(Loc::none(), Symbols::noClassOrModule(), Names::noMethod()); + MethodRef method = + enterMethodSymbol(Loc::none(), Symbols::noClassOrModule(), Names::noMethod(), LocOffsets::none()); ENFORCE(method == Symbols::noMethod()); FieldRef field = enterFieldSymbol(Loc::none(), Symbols::noClassOrModule(), Names::noFieldOrStaticField()); ENFORCE(field == Symbols::noField()); @@ -581,7 +582,7 @@ void GlobalState::initEmpty() { method = enterMethod(*this, Symbols::Class(), Names::new_()).repeatedArg(Names::args()).build(); ENFORCE(method == Symbols::Class_new()); - method = enterMethodSymbol(Loc::none(), Symbols::noClassOrModule(), Names::TodoMethod()); + method = enterMethodSymbol(Loc::none(), Symbols::noClassOrModule(), Names::TodoMethod(), LocOffsets::none()); enterMethodArgumentSymbol(Loc::none(), method, Names::args()); ENFORCE(method == Symbols::todoMethod()); @@ -887,7 +888,7 @@ void GlobalState::installIntrinsics() { break; } auto countBefore = methodsUsed(); - auto method = enterMethodSymbol(Loc::none(), symbol, entry.method); + auto method = enterMethodSymbol(Loc::none(), symbol, entry.method, LocOffsets::none()); method.data(*this)->intrinsicOffset = offset + Method::FIRST_VALID_INTRINSIC_OFFSET; if (countBefore != methodsUsed()) { auto &blkArg = enterMethodArgumentSymbol(Loc::none(), method, Names::blkArg()); @@ -1192,7 +1193,7 @@ TypeArgumentRef GlobalState::enterTypeArgument(Loc loc, MethodRef owner, NameRef return result; } -MethodRef GlobalState::enterMethodSymbol(Loc loc, ClassOrModuleRef owner, NameRef name) { +MethodRef GlobalState::enterMethodSymbol(Loc loc, ClassOrModuleRef owner, NameRef name, LocOffsets nameLoc) { ClassOrModuleData ownerScope = owner.dataAllowingNone(*this); histogramInc("symbol_enter_by_name", ownerScope->members().size()); @@ -1211,6 +1212,7 @@ MethodRef GlobalState::enterMethodSymbol(Loc loc, ClassOrModuleRef owner, NameRe MethodData data = result.dataAllowingNone(*this); data->name = name; + data->nameLoc = nameLoc; data->owner = owner; data->addLoc(*this, loc); DEBUG_ONLY(categoryCounterInc("symbols", "method")); @@ -1225,7 +1227,7 @@ MethodRef GlobalState::enterNewMethodOverload(Loc sigLoc, MethodRef original, co core::Loc loc = num == 0 ? original.data(*this)->loc() : sigLoc; // use original Loc for main overload so that we get right jump-to-def for it. auto owner = original.data(*this)->owner; - auto res = enterMethodSymbol(loc, owner, name); + auto res = enterMethodSymbol(loc, owner, name, original.data(*this)->nameLoc); bool newMethod = res != original; const auto &resArguments = res.data(*this)->arguments; ENFORCE(newMethod || !resArguments.empty(), "must be at least the block arg"); @@ -1723,6 +1725,8 @@ void GlobalState::mangleRenameSymbolInternal(SymbolRef what, NameRef origName, U } case SymbolRef::Kind::Method: what.asMethodRef().data(*this)->name = name; + // TODO(varun): This code path seems to be triggered when processing the stdlib. + // Should we be setting nameLoc here? break; case SymbolRef::Kind::FieldOrStaticField: what.asFieldRef().data(*this)->name = name; @@ -2342,7 +2346,8 @@ const vector> &GlobalState::getFiles() const { MethodRef GlobalState::staticInitForClass(ClassOrModuleRef klass, Loc loc) { auto prevCount = methodsUsed(); - auto sym = enterMethodSymbol(loc, klass.data(*this)->singletonClass(*this), core::Names::staticInit()); + auto sym = enterMethodSymbol(loc, klass.data(*this)->singletonClass(*this), core::Names::staticInit(), + klass.data(*this)->loc().offsets()); // TODO(varun): Check if this is OK if (prevCount != methodsUsed()) { auto blkLoc = core::Loc::none(loc.file()); auto &blkSym = enterMethodArgumentSymbol(blkLoc, sym, core::Names::blkArg()); @@ -2361,7 +2366,7 @@ MethodRef GlobalState::lookupStaticInitForClass(ClassOrModuleRef klass, bool all MethodRef GlobalState::staticInitForFile(Loc loc) { auto nm = freshNameUnique(core::UniqueNameKind::Namer, core::Names::staticInit(), loc.file().id()); auto prevCount = this->methodsUsed(); - auto sym = enterMethodSymbol(loc, core::Symbols::rootSingleton(), nm); + auto sym = enterMethodSymbol(loc, core::Symbols::rootSingleton(), nm, LocOffsets::none()); if (prevCount != this->methodsUsed()) { auto blkLoc = core::Loc::none(loc.file()); auto &blkSym = this->enterMethodArgumentSymbol(blkLoc, sym, core::Names::blkArg()); diff --git a/core/GlobalState.h b/core/GlobalState.h index 1040d86a8..6edef4a0a 100644 --- a/core/GlobalState.h +++ b/core/GlobalState.h @@ -102,7 +102,7 @@ class GlobalState final { ClassOrModuleRef enterClassSymbol(Loc loc, ClassOrModuleRef owner, NameRef name); TypeMemberRef enterTypeMember(Loc loc, ClassOrModuleRef owner, NameRef name, Variance variance); TypeArgumentRef enterTypeArgument(Loc loc, MethodRef owner, NameRef name, Variance variance); - MethodRef enterMethodSymbol(Loc loc, ClassOrModuleRef owner, NameRef name); + MethodRef enterMethodSymbol(Loc loc, ClassOrModuleRef owner, NameRef name, LocOffsets nameLoc); MethodRef enterNewMethodOverload(Loc loc, MethodRef original, core::NameRef originalName, uint32_t num, const std::vector &argsToKeep); FieldRef enterFieldSymbol(Loc loc, ClassOrModuleRef owner, NameRef name); diff --git a/core/Symbols.cc b/core/Symbols.cc index f8f123ad0..d5b3034c6 100644 --- a/core/Symbols.cc +++ b/core/Symbols.cc @@ -1840,7 +1840,7 @@ void ClassOrModule::recordRequiredAncestorInternal(GlobalState &gs, ClassOrModul // We store the required ancestors into a fake property called `` auto ancestors = this->findMethod(gs, prop); if (!ancestors.exists()) { - ancestors = gs.enterMethodSymbol(ancestor.loc, this->ref(gs), prop); + ancestors = gs.enterMethodSymbol(ancestor.loc, this->ref(gs), prop, LocOffsets::none()); ancestors.data(gs)->locs_.clear(); // Remove the original location // Create the return type tuple to store RequiredAncestor.symbol @@ -2140,7 +2140,8 @@ void Method::sanityCheck(const GlobalState &gs) const { return; } MethodRef current = this->ref(gs); - MethodRef current2 = const_cast(gs).enterMethodSymbol(this->loc(), this->owner, this->name); + MethodRef current2 = + const_cast(gs).enterMethodSymbol(this->loc(), this->owner, this->name, this->nameLoc); ENFORCE_NO_TIMER(current == current2); for (auto &tp : typeArguments()) { diff --git a/core/Symbols.h b/core/Symbols.h index f6efe5b9c..c4792795b 100644 --- a/core/Symbols.h +++ b/core/Symbols.h @@ -152,6 +152,7 @@ class Method final { ClassOrModuleRef owner; NameRef name; + core::LocOffsets nameLoc; ClassOrModuleRef rebind; Flags flags; // We store an offset into the intrinsic table used by calls.cc; the only @@ -188,7 +189,7 @@ class Method final { InlinedVector locs_; std::unique_ptr> typeArgs; }; -CheckSize(Method, 136, 8); +CheckSize(Method, 144, 8); // Contains a field or a static field class Field final { diff --git a/core/serialize/serialize.cc b/core/serialize/serialize.cc index 056ba3048..5b17dcd61 100644 --- a/core/serialize/serialize.cc +++ b/core/serialize/serialize.cc @@ -1241,6 +1241,7 @@ void SerializerImpl::pickle(Pickler &p, const ast::ExpressionPtr &what) { auto &c = ast::cast_tree_nonnull(what); pickle(p, c.loc); pickle(p, c.declLoc); + pickle(p, c.nameLoc); uint8_t flags; static_assert(sizeof(flags) == sizeof(c.flags)); // Can replace this with std::bit_cast in C++20 @@ -1518,6 +1519,7 @@ ast::ExpressionPtr SerializerImpl::unpickleExpr(serialize::UnPickler &p, const G case ast::Tag::MethodDef: { auto loc = unpickleLocOffsets(p); auto declLoc = unpickleLocOffsets(p); + auto nameLoc = unpickleLocOffsets(p); auto flagsU1 = p.getU1(); ast::MethodDef::Flags flags; static_assert(sizeof(flags) == sizeof(flagsU1)); @@ -1531,7 +1533,7 @@ ast::ExpressionPtr SerializerImpl::unpickleExpr(serialize::UnPickler &p, const G for (auto &arg : args) { arg = unpickleExpr(p, gs); } - auto ret = ast::MK::SyntheticMethod(loc, declLoc, name, std::move(args), std::move(rhs)); + auto ret = ast::MK::SyntheticMethod(loc, declLoc, nameLoc, name, std::move(args), std::move(rhs)); { auto &method = ast::cast_tree_nonnull(ret); diff --git a/namer/namer.cc b/namer/namer.cc index 8c0c41339..97a39d7ff 100644 --- a/namer/namer.cc +++ b/namer/namer.cc @@ -200,6 +200,7 @@ class SymbolFinder { foundMethod.name = method.name; foundMethod.loc = method.loc; foundMethod.declLoc = method.declLoc; + foundMethod.nameLoc = method.nameLoc; foundMethod.flags = method.flags; foundMethod.parsedArgs = ast::ArgParsing::parseArgs(method.args); foundMethod.arityHash = ast::ArgParsing::hashArgs(ctx, foundMethod.parsedArgs); @@ -338,6 +339,7 @@ class SymbolFinder { foundMethod.name = fromName; foundMethod.loc = send.loc; foundMethod.declLoc = send.loc; + foundMethod.nameLoc = send.loc; foundMethod.arityHash = core::ArityHash::aliasMethodHash(); foundDefs->addMethod(move(foundMethod)); } @@ -816,7 +818,7 @@ class SymbolDefiner { auto &parsedArgs = method.parsedArgs; auto symTableSize = ctx.state.methodsUsed(); auto declLoc = ctx.locAt(method.declLoc); - auto sym = ctx.state.enterMethodSymbol(declLoc, owner, method.name); + auto sym = ctx.state.enterMethodSymbol(declLoc, owner, method.name, method.nameLoc); const bool isNewSymbol = symTableSize != ctx.state.methodsUsed(); if (!isNewSymbol) { // See if this is == to the method we're defining now, or if we have a redefinition error. @@ -828,7 +830,7 @@ class SymbolDefiner { paramMismatchErrors(ctx.withOwner(sym), declLoc, parsedArgs); ctx.state.mangleRenameSymbol(sym, method.name); // Re-enter a new symbol. - sym = ctx.state.enterMethodSymbol(declLoc, owner, method.name); + sym = ctx.state.enterMethodSymbol(declLoc, owner, method.name, method.nameLoc); } else { // ...unless it's an intrinsic, because we allow multiple incompatible definitions of those in code // TODO(jvilk): Wouldn't this always fail since `!sym.exists()`? @@ -1022,8 +1024,8 @@ class SymbolDefiner { symbolData->flags.isSealed = true; auto classOfKlass = symbolData->singletonClass(ctx); - auto sealedSubclasses = - ctx.state.enterMethodSymbol(ctx.locAt(mod.loc), classOfKlass, core::Names::sealedSubclasses()); + auto sealedSubclasses = ctx.state.enterMethodSymbol( + ctx.locAt(mod.loc), classOfKlass, core::Names::sealedSubclasses(), core::LocOffsets::none()); auto &blkArg = ctx.state.enterMethodArgumentSymbol(core::Loc::none(), sealedSubclasses, core::Names::blkArg()); blkArg.flags.isBlock = true; diff --git a/parser/Builder.cc b/parser/Builder.cc index 942a5339d..399da3b64 100644 --- a/parser/Builder.cc +++ b/parser/Builder.cc @@ -846,11 +846,12 @@ class Builder::Impl { core::LocOffsets declLoc = head->loc.join(maybe_loc(args)); core::LocOffsets loc = head->loc.join(body->loc); std::string name = head->name.toString(gs_); + auto nameLoc = head->nameLoc; checkEndlessSetter(name, declLoc); checkReservedForNumberedParameters(name, declLoc); - return make_unique(loc, declLoc, gs_.enterNameUTF8(name), std::move(args), std::move(body)); + return make_unique(loc, declLoc, nameLoc, gs_.enterNameUTF8(name), std::move(args), std::move(body)); } unique_ptr defEndlessSingleton(unique_ptr defHead, unique_ptr args, const token *equal, @@ -863,7 +864,8 @@ class Builder::Impl { checkEndlessSetter(name, declLoc); checkReservedForNumberedParameters(name, declLoc); - return make_unique(loc, declLoc, std::move(head->definee), head->name, std::move(args), std::move(body)); + return make_unique(loc, declLoc, std::move(head->definee), head->nameLoc, head->name, std::move(args), + std::move(body)); } unique_ptr defMethod(unique_ptr defHead, unique_ptr args, unique_ptr body, @@ -872,10 +874,11 @@ class Builder::Impl { core::LocOffsets declLoc = head->loc.join(maybe_loc(args)); core::LocOffsets loc = head->loc.join(tokLoc(end)); std::string name = head->name.toString(gs_); + auto nameLoc = head->nameLoc; checkReservedForNumberedParameters(name, declLoc); - return make_unique(loc, declLoc, gs_.enterNameUTF8(name), std::move(args), std::move(body)); + return make_unique(loc, declLoc, nameLoc, gs_.enterNameUTF8(name), std::move(args), std::move(body)); } unique_ptr defModule(const token *module, unique_ptr name, unique_ptr body, const token *end_) { @@ -886,8 +889,9 @@ class Builder::Impl { unique_ptr defnHead(const token *def, const token *name) { core::LocOffsets declLoc = tokLoc(def, name); + auto nameLoc = tokLoc(name); - return make_unique(declLoc, gs_.enterNameUTF8(name->view())); + return make_unique(declLoc, nameLoc, gs_.enterNameUTF8(name->view())); } unique_ptr def_sclass(const token *class_, const token *lshft_, unique_ptr expr, unique_ptr body, @@ -898,19 +902,20 @@ class Builder::Impl { } unique_ptr defnHeadError(const token *def) { - return make_unique(tokLoc(def), core::Names::methodDefNameMissing()); + return make_unique(tokLoc(def), core::LocOffsets::none(), core::Names::methodDefNameMissing()); } unique_ptr defsHead(const token *def, unique_ptr definee, const token *dot, const token *name) { core::LocOffsets declLoc = tokLoc(def, name); - return make_unique(declLoc, std::move(definee), gs_.enterNameUTF8(name->view())); + return make_unique(declLoc, std::move(definee), tokLoc(name), gs_.enterNameUTF8(name->view())); } unique_ptr defsHeadError(const token *def, unique_ptr definee, const token *dot) { core::LocOffsets declLoc = tokLoc(def, dot); - return make_unique(declLoc, std::move(definee), core::Names::methodDefNameMissing()); + return make_unique(declLoc, std::move(definee), core::LocOffsets::none(), + core::Names::methodDefNameMissing()); } unique_ptr defSingleton(unique_ptr defHead, unique_ptr args, unique_ptr body, @@ -924,7 +929,8 @@ class Builder::Impl { } checkReservedForNumberedParameters(head->name.toString(gs_), declLoc); - return make_unique(loc, declLoc, std::move(head->definee), head->name, std::move(args), std::move(body)); + return make_unique(loc, declLoc, std::move(head->definee), head->nameLoc, head->name, std::move(args), + std::move(body)); } unique_ptr empty_else(const token *tok) { diff --git a/parser/tools/generate_ast.cc b/parser/tools/generate_ast.cc index 9497b7e0e..f6328988f 100644 --- a/parser/tools/generate_ast.cc +++ b/parser/tools/generate_ast.cc @@ -194,6 +194,7 @@ NodeDef nodes[] = { "DefMethod", "def", vector({{"declLoc", FieldType::Loc}, + {"nameLoc", FieldType::Loc}, {"name", FieldType::Name}, {"args", FieldType::Node}, {"body", FieldType::Node}}), @@ -205,13 +206,14 @@ NodeDef nodes[] = { vector({{"value", FieldType::Node}}), }, // def name, instance method def - {"DefnHead", "defnhead", vector({{"name", FieldType::Name}})}, + {"DefnHead", "defnhead", vector({{"nameLoc", FieldType::Loc}, {"name", FieldType::Name}})}, // def .name singleton-class method def { "DefS", "defs", vector({{"declLoc", FieldType::Loc}, {"singleton", FieldType::Node}, + {"nameLoc", FieldType::Loc}, {"name", FieldType::Name}, {"args", FieldType::Node}, {"body", FieldType::Node}}), @@ -222,6 +224,7 @@ NodeDef nodes[] = { "defshead", vector({ {"definee", FieldType::Node}, + {"nameLoc", FieldType::Loc}, {"name", FieldType::Name}, }), }, @@ -1040,10 +1043,12 @@ void emitNodeClassfile(ostream &out, NodeDef &node) { << maybeComma << "\\n\", " << arg.name << ");\n"; break; case FieldType::Loc: + out << "{\n"; out << " bool showFull = true;"; out << R"( fmt::format_to(std::back_inserter(buf), "\")" << arg.name << R"(\" : \"{}\")" << maybeComma << "\\n\", " << "core::Loc(file, " << arg.name << ").filePosToString(gs, showFull));\n"; + out << "}\n"; break; case FieldType::Bool: out << R"( fmt::format_to(std::back_inserter(buf), "\")" << arg.name << R"(\" : \"{}\")" diff --git a/resolver/resolver.cc b/resolver/resolver.cc index 921547c50..624f332d0 100644 --- a/resolver/resolver.cc +++ b/resolver/resolver.cc @@ -880,7 +880,8 @@ class ResolveConstantsWalk { auto ancestorType = core::make_type(unresolvedPath->first, move(unresolvedPath->second)); - auto uaSym = ctx.state.enterMethodSymbol(core::Loc::none(), item.klass, core::Names::unresolvedAncestors()); + auto uaSym = ctx.state.enterMethodSymbol(core::Loc::none(), item.klass, core::Names::unresolvedAncestors(), + core::LocOffsets::none()); // Add a fake block argument so that this method symbol passes sanity checks auto &arg = ctx.state.enterMethodArgumentSymbol(core::Loc::none(), uaSym, core::Names::blkArg()); @@ -1073,7 +1074,7 @@ class ResolveConstantsWalk { // We never stored a mixin in this symbol // Create a the fake property that will hold the mixed in modules mixMethod = gs.enterMethodSymbol(core::Loc{todo.file, send->loc}, ownerKlass, - core::Names::mixedInClassMethods()); + core::Names::mixedInClassMethods(), core::LocOffsets::none()); mixMethod.data(gs)->resultType = core::make_type(vector{}); // Create a dummy block argument to satisfy sanitycheck during GlobalState::expandNames @@ -2438,7 +2439,8 @@ class ResolveTypeMembersAndFieldsWalk { return; } - auto alias = ctx.state.enterMethodSymbol(ctx.locAt(job.loc), job.owner, job.fromName); + // TODO(varun): is toNameLoc the right field? + auto alias = ctx.state.enterMethodSymbol(ctx.locAt(job.loc), job.owner, job.fromName, job.toNameLoc); alias.data(ctx)->resultType = core::make_type(core::SymbolRef(toMethod)); // Add a fake keyword argument to remember the toName (for fast path hashing). diff --git a/rewriter/AttrReader.cc b/rewriter/AttrReader.cc index 4e783ef9c..7cb08f687 100644 --- a/rewriter/AttrReader.cc +++ b/rewriter/AttrReader.cc @@ -301,7 +301,7 @@ vector AttrReader::run(core::MutableContext ctx, ast::Send * if (sigIsUnchecked(ctx, sig)) { flags.isAttrReader = true; } - auto reader = ast::MK::SyntheticMethod0(loc, loc, name, ast::MK::Instance(argLoc, varName), flags); + auto reader = ast::MK::SyntheticMethod0(loc, loc, argLoc, name, ast::MK::Instance(argLoc, varName), flags); stats.emplace_back(std::move(reader)); } } @@ -337,7 +337,8 @@ vector AttrReader::run(core::MutableContext ctx, ast::Send * } else { body = ast::MK::Assign(loc, ast::MK::Instance(argLoc, varName), ast::MK::Local(loc, name)); } - stats.emplace_back(ast::MK::SyntheticMethod1(loc, loc, setName, ast::MK::Local(argLoc, name), move(body))); + stats.emplace_back( + ast::MK::SyntheticMethod1(loc, loc, argLoc, setName, ast::MK::Local(argLoc, name), move(body))); } } diff --git a/rewriter/Command.cc b/rewriter/Command.cc index 55e63c601..64392295a 100644 --- a/rewriter/Command.cc +++ b/rewriter/Command.cc @@ -84,7 +84,7 @@ void Command::run(core::MutableContext ctx, ast::ClassDef *klass) { ast::MethodDef::Flags flags; flags.isSelfMethod = true; flags.discardDef = true; - auto selfCall = ast::MK::SyntheticMethod(call->loc, call->loc, call->name, std::move(newArgs), + auto selfCall = ast::MK::SyntheticMethod(call->loc, call->loc, call->loc, call->name, std::move(newArgs), ast::MK::UntypedNil(call->loc), flags); klass->rhs.insert(klass->rhs.begin() + i + 1, sig->deepCopy()); diff --git a/rewriter/DSLBuilder.cc b/rewriter/DSLBuilder.cc index f24fd2fa4..40106a34c 100644 --- a/rewriter/DSLBuilder.cc +++ b/rewriter/DSLBuilder.cc @@ -53,6 +53,8 @@ vector DSLBuilder::run(core::MutableContext ctx, ast::Send * ENFORCE(!ctx.locAt(sym->loc).source(ctx).value().empty() && ctx.locAt(sym->loc).source(ctx).value()[0] == ':'); auto nameLoc = core::LocOffsets{sym->loc.beginPos() + 1, sym->loc.endPos()}; + fmt::print(stderr, "log: [DSLBuilder::run] name = {} @ {}\n", name.toString(ctx), ctx.locAt(nameLoc).showRaw(ctx)); + type = ASTUtil::dupType(send->getPosArg(1)); if (!type) { return empty; @@ -93,7 +95,7 @@ vector DSLBuilder::run(core::MutableContext ctx, ast::Send * auto default_ = ast::MK::UntypedNil(loc); arg = ast::MK::OptionalArg(loc, move(arg), move(default_)); } - auto defSelfProp = ast::MK::SyntheticMethod1(loc, loc, name, move(arg), ast::MK::EmptyTree(), flags); + auto defSelfProp = ast::MK::SyntheticMethod1(loc, loc, nameLoc, name, move(arg), ast::MK::EmptyTree(), flags); ast::cast_tree(defSelfProp)->flags.isSelfMethod = true; stats.emplace_back(move(defSelfProp)); } @@ -106,13 +108,16 @@ vector DSLBuilder::run(core::MutableContext ctx, ast::Send * // def self.get_ core::NameRef getName = ctx.state.enterNameUTF8("get_" + name.show(ctx)); stats.emplace_back(ast::MK::Sig0(loc, ASTUtil::dupType(type))); - auto defSelfGetProp = ast::MK::SyntheticMethod(loc, loc, getName, {}, ast::MK::RaiseUnimplemented(loc), flags); + // TODO(varun): Get proper location here + auto defSelfGetProp = + ast::MK::SyntheticMethod(loc, loc, loc, getName, {}, ast::MK::RaiseUnimplemented(loc), flags); ast::cast_tree(defSelfGetProp)->flags.isSelfMethod = true; stats.emplace_back(move(defSelfGetProp)); + // TODO(varun): Get proper location here // def () stats.emplace_back(ast::MK::Sig0(loc, ASTUtil::dupType(type))); - stats.emplace_back(ast::MK::SyntheticMethod(loc, loc, name, {}, ast::MK::RaiseUnimplemented(loc), flags)); + stats.emplace_back(ast::MK::SyntheticMethod(loc, loc, loc, name, {}, ast::MK::RaiseUnimplemented(loc), flags)); } return stats; diff --git a/rewriter/DefDelegator.cc b/rewriter/DefDelegator.cc index 2aebda0a3..94cbb927c 100644 --- a/rewriter/DefDelegator.cc +++ b/rewriter/DefDelegator.cc @@ -24,7 +24,7 @@ void generateStub(vector &methodStubs, const core::LocOffset args.emplace_back(ast::make_expression(loc, ast::MK::Local(loc, core::Names::blkArg()))); methodStubs.push_back( - ast::MK::SyntheticMethod(loc, loc, methodName, std::move(args), ast::MK::RaiseUnimplemented(loc))); + ast::MK::SyntheticMethod(loc, loc, loc, methodName, std::move(args), ast::MK::RaiseUnimplemented(loc))); } /// Handle #def_delegator for a single delegate method diff --git a/rewriter/Delegate.cc b/rewriter/Delegate.cc index 602310e1a..c869a9c80 100644 --- a/rewriter/Delegate.cc +++ b/rewriter/Delegate.cc @@ -117,7 +117,8 @@ vector Delegate::run(core::MutableContext ctx, const ast::Se args.emplace_back(ast::MK::RestArg(loc, ast::MK::Local(loc, core::Names::arg0()))); args.emplace_back(ast::make_expression(loc, ast::MK::Local(loc, core::Names::blkArg()))); - methodStubs.push_back(ast::MK::SyntheticMethod(loc, loc, methodName, std::move(args), ast::MK::EmptyTree())); + methodStubs.push_back( + ast::MK::SyntheticMethod(loc, loc, loc, methodName, std::move(args), ast::MK::EmptyTree())); } return methodStubs; diff --git a/rewriter/Flatfiles.cc b/rewriter/Flatfiles.cc index 9d753d1ea..3354dd3ac 100644 --- a/rewriter/Flatfiles.cc +++ b/rewriter/Flatfiles.cc @@ -48,13 +48,14 @@ void handleFieldDefinition(core::MutableContext ctx, ast::ExpressionPtr &stat, v } methods.emplace_back(ast::MK::Sig0(send->loc, ast::MK::Untyped(send->loc))); - methods.emplace_back(ast::MK::SyntheticMethod0(send->loc, send->loc, *name, ast::MK::Nil(send->loc))); + methods.emplace_back( + ast::MK::SyntheticMethod0(send->loc, send->loc, send->loc, *name, ast::MK::Nil(send->loc))); auto var = ast::MK::Local(send->loc, core::Names::arg0()); auto setName = name->addEq(ctx); methods.emplace_back(ast::MK::Sig1(send->loc, ast::MK::Symbol(send->loc, core::Names::arg0()), ast::MK::Untyped(send->loc), ast::MK::Untyped(send->loc))); methods.emplace_back( - ast::MK::SyntheticMethod1(send->loc, send->loc, setName, move(var), ast::MK::Nil(send->loc))); + ast::MK::SyntheticMethod1(send->loc, send->loc, send->loc, setName, move(var), ast::MK::Nil(send->loc))); } } diff --git a/rewriter/Mattr.cc b/rewriter/Mattr.cc index 492cdfbd1..ea43f3f55 100644 --- a/rewriter/Mattr.cc +++ b/rewriter/Mattr.cc @@ -95,7 +95,7 @@ vector Mattr::run(core::MutableContext ctx, const ast::Send auto loc = lit->loc; if (doReaders) { auto sig = ast::MK::Sig0(loc, ast::MK::Untyped(loc)); - auto def = ast::MK::SyntheticMethod0(loc, loc, lit->asSymbol(), ast::MK::EmptyTree()); + auto def = ast::MK::SyntheticMethod0(loc, loc, loc, lit->asSymbol(), ast::MK::EmptyTree()); ast::cast_tree_nonnull(def).flags.isSelfMethod = true; if (instanceReader) { addInstanceCounterPart(result, sig, def); @@ -106,7 +106,7 @@ vector Mattr::run(core::MutableContext ctx, const ast::Send if (doWriters) { auto sig = ast::MK::Sig1(loc, ast::MK::Symbol(loc, core::Names::arg0()), ast::MK::Untyped(loc), ast::MK::Untyped(loc)); - auto def = ast::MK::SyntheticMethod1(loc, loc, lit->asSymbol().addEq(ctx), + auto def = ast::MK::SyntheticMethod1(loc, loc, loc, lit->asSymbol().addEq(ctx), ast::MK::Local(loc, core::Names::arg0()), ast::MK::EmptyTree()); ast::cast_tree_nonnull(def).flags.isSelfMethod = true; if (instanceWriter) { @@ -120,7 +120,7 @@ vector Mattr::run(core::MutableContext ctx, const ast::Send // from being generated. auto sig = ast::MK::Sig0( loc, ast::MK::UnresolvedConstant(loc, ast::MK::T(loc), core::Names::Constants::Boolean())); - auto def = ast::MK::SyntheticMethod0(loc, loc, lit->asSymbol().addQuestion(ctx), ast::MK::False(loc)); + auto def = ast::MK::SyntheticMethod0(loc, loc, loc, lit->asSymbol().addQuestion(ctx), ast::MK::False(loc)); ast::cast_tree_nonnull(def).flags.isSelfMethod = true; if (instanceReader && instancePredicate) { addInstanceCounterPart(result, sig, def); diff --git a/rewriter/Minitest.cc b/rewriter/Minitest.cc index 4bdca0662..c97ab7ad7 100644 --- a/rewriter/Minitest.cc +++ b/rewriter/Minitest.cc @@ -220,7 +220,8 @@ ast::ExpressionPtr runUnderEach(core::MutableContext ctx, core::NameRef eachName auto each = ast::MK::Send0Block(send->loc, iteratee.deepCopy(), core::Names::each(), send->loc.copyWithZeroLength(), move(blk)); // put that into a method def named the appropriate thing - auto method = addSigVoid(ast::MK::SyntheticMethod0(send->loc, send->loc, move(name), move(each))); + auto method = + addSigVoid(ast::MK::SyntheticMethod0(send->loc, send->loc, send->loc, move(name), move(each))); // add back any moved constants return constantMover.addConstantsToExpression(send->loc, move(method)); } @@ -356,8 +357,8 @@ ast::ExpressionPtr runSingle(core::MutableContext ctx, bool isClass, ast::Send * auto name = send->fun == core::Names::after() ? core::Names::afterAngles() : core::Names::initialize(); ConstantMover constantMover; ast::TreeWalk::apply(ctx, constantMover, block->body); - auto method = addSigVoid( - ast::MK::SyntheticMethod0(send->loc, send->loc, name, prepareBody(ctx, isClass, std::move(block->body)))); + auto method = addSigVoid(ast::MK::SyntheticMethod0(send->loc, send->loc, send->loc, name, + prepareBody(ctx, isClass, std::move(block->body)))); return constantMover.addConstantsToExpression(send->loc, move(method)); } @@ -387,7 +388,7 @@ ast::ExpressionPtr runSingle(core::MutableContext ctx, bool isClass, ast::Send * ast::TreeWalk::apply(ctx, constantMover, block->body); auto name = ctx.state.enterNameUTF8(""); const bool bodyIsClass = false; - auto method = addSigVoid(ast::MK::SyntheticMethod0(send->loc, send->loc, std::move(name), + auto method = addSigVoid(ast::MK::SyntheticMethod0(send->loc, send->loc, send->loc, std::move(name), prepareBody(ctx, bodyIsClass, std::move(block->body)))); method = ast::MK::InsSeq1(send->loc, send->getPosArg(0).deepCopy(), move(method)); return constantMover.addConstantsToExpression(send->loc, move(method)); diff --git a/rewriter/MixinEncryptedProp.cc b/rewriter/MixinEncryptedProp.cc index 31b8ac979..6d202f4d7 100644 --- a/rewriter/MixinEncryptedProp.cc +++ b/rewriter/MixinEncryptedProp.cc @@ -70,10 +70,10 @@ vector MixinEncryptedProp::run(core::MutableContext ctx, ast // Compute the getters stats.emplace_back(ast::MK::Sig(loc, {}, mkNilableString(loc))); - stats.emplace_back(ASTUtil::mkGet(ctx, loc, name, ast::MK::RaiseUnimplemented(loc))); + stats.emplace_back(ASTUtil::mkGet(ctx, loc, name, nameLoc, ast::MK::RaiseUnimplemented(loc))); stats.emplace_back(ast::MK::Sig(loc, {}, mkNilableEncryptedValue(ctx, loc))); - stats.emplace_back(ASTUtil::mkGet(ctx, loc, enc_name, ast::MK::RaiseUnimplemented(loc))); + stats.emplace_back(ASTUtil::mkGet(ctx, loc, enc_name, nameLoc, ast::MK::RaiseUnimplemented(loc))); core::NameRef setName = name.addEq(ctx); core::NameRef setEncName = enc_name.addEq(ctx); diff --git a/rewriter/ModuleFunction.cc b/rewriter/ModuleFunction.cc index d20e33200..9745ca281 100644 --- a/rewriter/ModuleFunction.cc +++ b/rewriter/ModuleFunction.cc @@ -138,7 +138,7 @@ vector ModuleFunction::run(core::MutableContext ctx, ast::Se ast::MethodDef::ARGS_store args; args.emplace_back(ast::MK::RestArg(loc, ast::MK::Local(loc, core::Names::arg0()))); args.emplace_back(ast::make_expression(loc, ast::MK::Local(loc, core::Names::blkArg()))); - auto methodDef = ast::MK::SyntheticMethod(loc, loc, methodName, std::move(args), ast::MK::EmptyTree()); + auto methodDef = ast::MK::SyntheticMethod(loc, loc, loc, methodName, std::move(args), ast::MK::EmptyTree()); ast::cast_tree_nonnull(methodDef).flags.isSelfMethod = true; stats.emplace_back(std::move(methodDef)); } else { diff --git a/rewriter/Prop.cc b/rewriter/Prop.cc index 8f8d2970d..e0acd95ef 100644 --- a/rewriter/Prop.cc +++ b/rewriter/Prop.cc @@ -353,6 +353,8 @@ vector processProp(core::MutableContext ctx, PropInfo &ret, const auto name = ret.name; const auto nameLoc = ret.nameLoc; + fmt::print(stderr, "log: [processProp] name = {} @ {}\n", name.toString(ctx), ctx.locAt(nameLoc).showRaw(ctx)); + const auto getType = ASTUtil::dupType(ret.type); const auto computedByMethodName = ret.computedByMethodName; @@ -378,21 +380,22 @@ vector processProp(core::MutableContext ctx, PropInfo &ret, auto assertTypeMatches = ast::MK::AssertType(computedByMethodNameLoc, std::move(sendComputedMethod), ASTUtil::dupType(getType)); auto insSeq = ast::MK::InsSeq1(loc, std::move(assertTypeMatches), ast::MK::RaiseUnimplemented(loc)); - nodes.emplace_back(ASTUtil::mkGet(ctx, loc, name, std::move(insSeq))); + nodes.emplace_back(ASTUtil::mkGet(ctx, loc, name, nameLoc, std::move(insSeq))); } else if (propContext.needsRealPropBodies && propContext.classDefKind == ast::ClassDef::Kind::Module) { // Not all modules include Kernel, can't make an initialize, etc. so we're punting on props in modules rn. - nodes.emplace_back(ASTUtil::mkGet(ctx, loc, name, ast::MK::RaiseUnimplemented(loc))); + nodes.emplace_back(ASTUtil::mkGet(ctx, loc, name, nameLoc, ast::MK::RaiseUnimplemented(loc))); } else if (ret.ifunset == nullptr) { if (knownNonModel(propContext.syntacticSuperClass)) { ast::MethodDef::Flags flags; flags.isAttrReader = true; if (wantTypedInitialize(propContext.syntacticSuperClass)) { - nodes.emplace_back(ASTUtil::mkGet(ctx, loc, name, ast::MK::Instance(nameLoc, ivarName), flags)); + nodes.emplace_back( + ASTUtil::mkGet(ctx, loc, name, nameLoc, ast::MK::Instance(nameLoc, ivarName), flags)); } else { // Need to hide the instance variable access, because there wasn't a typed constructor to declare it auto ivarGet = ast::MK::Send1(loc, ast::MK::Self(loc), core::Names::instanceVariableGet(), locZero, ast::MK::Symbol(nameLoc, ivarName)); - nodes.emplace_back(ASTUtil::mkGet(ctx, loc, name, std::move(ivarGet), flags)); + nodes.emplace_back(ASTUtil::mkGet(ctx, loc, name, nameLoc, std::move(ivarGet), flags)); } } else if (propContext.needsRealPropBodies) { ast::MethodDef::Flags flags; @@ -414,12 +417,12 @@ vector processProp(core::MutableContext ctx, PropInfo &ret, ast::MK::Self(loc), ast::MK::Symbol(nameLoc, name), std::move(arg2)); auto insSeq = ast::MK::InsSeq1(loc, std::move(assign), std::move(propGetLogic)); - nodes.emplace_back(ASTUtil::mkGet(ctx, loc, name, std::move(insSeq), flags)); + nodes.emplace_back(ASTUtil::mkGet(ctx, loc, name, nameLoc, std::move(insSeq), flags)); } else { - nodes.emplace_back(ASTUtil::mkGet(ctx, loc, name, ast::MK::RaiseUnimplemented(loc))); + nodes.emplace_back(ASTUtil::mkGet(ctx, loc, name, nameLoc, ast::MK::RaiseUnimplemented(loc))); } } else { - nodes.emplace_back(ASTUtil::mkGet(ctx, loc, name, ast::MK::RaiseUnimplemented(loc))); + nodes.emplace_back(ASTUtil::mkGet(ctx, loc, name, nameLoc, ast::MK::RaiseUnimplemented(loc))); } core::NameRef setName = name.addEq(ctx); @@ -494,8 +497,8 @@ vector processProp(core::MutableContext ctx, PropInfo &ret, auto arg = ast::MK::KeywordArgWithDefault(nameLoc, core::Names::allowDirectMutation(), ast::MK::Nil(loc)); ast::MethodDef::Flags fkFlags; fkFlags.discardDef = true; - auto fkMethodDef = - ast::MK::SyntheticMethod1(loc, loc, fkMethod, std::move(arg), ast::MK::RaiseUnimplemented(loc), fkFlags); + auto fkMethodDef = ast::MK::SyntheticMethod1(loc, loc, nameLoc, fkMethod, std::move(arg), + ast::MK::RaiseUnimplemented(loc), fkFlags); nodes.emplace_back(std::move(fkMethodDef)); // sig {params(opts: T.untyped).returns($foreign)} @@ -510,7 +513,7 @@ vector processProp(core::MutableContext ctx, PropInfo &ret, auto arg2 = ast::MK::KeywordArgWithDefault(nameLoc, core::Names::allowDirectMutation(), ast::MK::Nil(loc)); ast::MethodDef::Flags fkBangFlags; fkBangFlags.discardDef = true; - auto fkMethodDefBang = ast::MK::SyntheticMethod1(loc, loc, fkMethodBang, std::move(arg2), + auto fkMethodDefBang = ast::MK::SyntheticMethod1(loc, loc, nameLoc, fkMethodBang, std::move(arg2), ast::MK::RaiseUnimplemented(loc), fkBangFlags); nodes.emplace_back(std::move(fkMethodDefBang)); } @@ -596,8 +599,9 @@ vector mkTypedInitialize(core::MutableContext ctx, core::Loc vector result; result.emplace_back(ast::MK::SigVoid(klassDeclLoc, std::move(sigArgs))); - result.emplace_back( - ast::MK::SyntheticMethod(klassLoc, klassDeclLoc, core::Names::initialize(), std::move(args), std::move(body))); + // TODO(varun): What does klassDeclLoc correspond to? + result.emplace_back(ast::MK::SyntheticMethod(klassLoc, klassDeclLoc, klassDeclLoc, core::Names::initialize(), + std::move(args), std::move(body))); return result; } diff --git a/rewriter/Singleton.cc b/rewriter/Singleton.cc index 65b46a881..9bb6dccea 100644 --- a/rewriter/Singleton.cc +++ b/rewriter/Singleton.cc @@ -84,7 +84,9 @@ void Singleton::run(core::MutableContext ctx, ast::ClassDef *cdef) { } { - auto method = ast::MK::SyntheticMethod0(loc, loc, core::Names::instance(), ast::MK::RaiseUnimplemented(loc)); + // TODO(varun): Not sure if 'loc' is the right 'nameLoc' here. + auto method = + ast::MK::SyntheticMethod0(loc, loc, loc, core::Names::instance(), ast::MK::RaiseUnimplemented(loc)); ast::cast_tree_nonnull(method).flags.isSelfMethod = true; newRHS.emplace_back(std::move(method)); } diff --git a/rewriter/Struct.cc b/rewriter/Struct.cc index c731e5a3c..4fc83be1e 100644 --- a/rewriter/Struct.cc +++ b/rewriter/Struct.cc @@ -138,10 +138,10 @@ vector Struct::run(core::MutableContext ctx, ast::Assign *as argName = ast::make_expression(symLoc, move(argName)); } newArgs.emplace_back(ast::MK::OptionalArg(symLoc, move(argName), ast::MK::Nil(symLoc))); - - body.emplace_back(ast::MK::SyntheticMethod0(symLoc, symLoc, name, ast::MK::RaiseUnimplemented(loc))); - body.emplace_back(ast::MK::SyntheticMethod1(symLoc, symLoc, name.addEq(ctx), ast::MK::Local(symLoc, name), - ast::MK::RaiseUnimplemented(loc))); + // TODO(varun): Is symLoc correct here? + body.emplace_back(ast::MK::SyntheticMethod0(symLoc, symLoc, symLoc, name, ast::MK::RaiseUnimplemented(loc))); + body.emplace_back(ast::MK::SyntheticMethod1(symLoc, symLoc, symLoc, name.addEq(ctx), + ast::MK::Local(symLoc, name), ast::MK::RaiseUnimplemented(loc))); } // Elem = type_member {{fixed: T.untyped}} @@ -157,7 +157,7 @@ vector Struct::run(core::MutableContext ctx, ast::Assign *as if (isMissingInitialize(ctx, send)) { body.emplace_back(ast::MK::SigVoid(loc, std::move(sigArgs))); - body.emplace_back(ast::MK::SyntheticMethod(loc, loc, core::Names::initialize(), std::move(newArgs), + body.emplace_back(ast::MK::SyntheticMethod(loc, loc, loc, core::Names::initialize(), std::move(newArgs), ast::MK::RaiseUnimplemented(loc))); } diff --git a/rewriter/TestCase.cc b/rewriter/TestCase.cc index 5c8a17819..b413dc369 100644 --- a/rewriter/TestCase.cc +++ b/rewriter/TestCase.cc @@ -40,7 +40,7 @@ void TestCase::run(core::MutableContext ctx, ast::ClassDef *klass) { auto snake_case_name = absl::StrReplaceAll(arg0->asString().toString(ctx), {{" ", "_"}}); auto name = ctx.state.enterNameUTF8("test_" + snake_case_name); - auto method = ast::MK::SyntheticMethod0(loc, loc, name, std::move(block->body)); + auto method = ast::MK::SyntheticMethod0(loc, loc, loc, name, std::move(block->body)); auto method_with_sig = ast::MK::InsSeq1(method.loc(), ast::MK::SigVoid(method.loc(), {}), std::move(method)); stats.emplace_back(std::move(method_with_sig)); @@ -55,7 +55,7 @@ void TestCase::run(core::MutableContext ctx, ast::ClassDef *klass) { auto block = send->block(); auto method_name = send->fun == core::Names::setup() ? core::Names::initialize() : core::Names::teardown(); - auto method = ast::MK::SyntheticMethod0(loc, loc, method_name, std::move(block->body)); + auto method = ast::MK::SyntheticMethod0(loc, loc, loc, method_name, std::move(block->body)); auto method_with_sig = ast::MK::InsSeq1(method.loc(), ast::MK::SigVoid(method.loc(), {}), std::move(method)); diff --git a/rewriter/Util.cc b/rewriter/Util.cc index ea0590a71..d191358bf 100644 --- a/rewriter/Util.cc +++ b/rewriter/Util.cc @@ -249,15 +249,16 @@ ast::ExpressionPtr ASTUtil::mkKwArgsHash(const ast::Send *send) { } } -ast::ExpressionPtr ASTUtil::mkGet(core::Context ctx, core::LocOffsets loc, core::NameRef name, ast::ExpressionPtr rhs, - ast::MethodDef::Flags flags) { - auto ret = ast::MK::SyntheticMethod0(loc, loc, name, move(rhs), flags); +ast::ExpressionPtr ASTUtil::mkGet(core::Context ctx, core::LocOffsets loc, core::NameRef name, core::LocOffsets nameLoc, + ast::ExpressionPtr rhs, ast::MethodDef::Flags flags) { + auto ret = ast::MK::SyntheticMethod0(loc, loc, nameLoc, name, move(rhs), flags); return ret; } -ast::ExpressionPtr ASTUtil::mkSet(core::Context ctx, core::LocOffsets loc, core::NameRef name, core::LocOffsets argLoc, +ast::ExpressionPtr ASTUtil::mkSet(core::Context ctx, core::LocOffsets loc, core::NameRef name, core::LocOffsets nameLoc, ast::ExpressionPtr rhs, ast::MethodDef::Flags flags) { - return ast::MK::SyntheticMethod1(loc, loc, name, ast::MK::Local(argLoc, core::Names::arg0()), move(rhs), flags); + return ast::MK::SyntheticMethod1(loc, loc, nameLoc, name, ast::MK::Local(nameLoc, core::Names::arg0()), move(rhs), + flags); } ast::ExpressionPtr ASTUtil::mkNilable(core::LocOffsets loc, ast::ExpressionPtr type) { diff --git a/rewriter/Util.h b/rewriter/Util.h index b985d3b7c..45b3df776 100644 --- a/rewriter/Util.h +++ b/rewriter/Util.h @@ -21,11 +21,12 @@ class ASTUtil { static ast::ExpressionPtr mkKwArgsHash(const ast::Send *send); - static ast::ExpressionPtr mkGet(core::Context ctx, core::LocOffsets loc, core::NameRef name, ast::ExpressionPtr rhs, + static ast::ExpressionPtr mkGet(core::Context ctx, core::LocOffsets loc, core::NameRef name, + core::LocOffsets nameLoc, ast::ExpressionPtr rhs, ast::MethodDef::Flags flags = ast::MethodDef::Flags()); static ast::ExpressionPtr mkSet(core::Context ctx, core::LocOffsets loc, core::NameRef name, - core::LocOffsets argLoc, ast::ExpressionPtr rhs, + core::LocOffsets nameLoc, ast::ExpressionPtr rhs, ast::MethodDef::Flags flags = ast::MethodDef::Flags()); static ast::ExpressionPtr mkNilable(core::LocOffsets loc, ast::ExpressionPtr type); diff --git a/scip_indexer/SCIPIndexer.cc b/scip_indexer/SCIPIndexer.cc index 1f5250cf9..9cce9248a 100644 --- a/scip_indexer/SCIPIndexer.cc +++ b/scip_indexer/SCIPIndexer.cc @@ -392,10 +392,23 @@ class NamedSymbolRef final { return absl::OkStatus(); } - core::Loc symbolLoc(const core::GlobalState &gs) const { - // FIXME(varun): For methods, this returns the full line! - ENFORCE(this->name == core::NameRef::noName()); - return this->selfOrOwner.loc(gs); + core::Loc symbolLoc(const core::GlobalState &gs, core::FileRef file) const { + switch (this->kind()) { + case Kind::Method: { + auto method = this->selfOrOwner.asMethodRef().data(gs); + auto offset = method->nameLoc; + if (!offset.exists() || offset.empty()) { + fmt::print("Missing nameLoc for {}\n", this->showRaw(gs)); + return method->loc(); + } + return core::Loc(file, offset); + } + case Kind::ClassOrModule: + case Kind::DeclaredField: + return this->selfOrOwner.loc(gs); + case Kind::UndeclaredField: + ENFORCE(false, "case UndeclaredField should not be triggered here"); + } } }; @@ -628,7 +641,7 @@ class SCIPState { std::optional loc = std::nullopt) { // TODO:(varun) Should we cache here too to avoid emitting duplicate definitions? scip::Symbol symbol; - auto occLoc = loc.has_value() ? core::Loc(file, loc.value()) : symRef.symbolLoc(gs); + auto occLoc = loc.has_value() ? core::Loc(file, loc.value()) : symRef.symbolLoc(gs, file); auto status = symRef.symbolForExpr(gs, this->gemMetadata, symbol, occLoc); if (!status.ok()) { return status; diff --git a/test/hello-test.cc b/test/hello-test.cc index 08828ff89..cd8966c6d 100644 --- a/test/hello-test.cc +++ b/test/hello-test.cc @@ -123,7 +123,7 @@ TEST_CASE("CountTrees") { // see if it crashes via failed ENFORCE cb.enterTypeMember(loc, classSym, cb.enterNameConstant(name), sorbet::core::Variance::CoVariant); - auto methodSym = cb.enterMethodSymbol(loc, classSym, name); + auto methodSym = cb.enterMethodSymbol(loc, classSym, name, core::LocOffsets::none()); // see if it crashes via failed ENFORCE cb.enterTypeArgument(loc, methodSym, cb.enterNameConstant(name), sorbet::core::Variance::CoVariant); diff --git a/test/scip/testdata/args.snapshot.rb b/test/scip/testdata/args.snapshot.rb index 5a33b7c57..bc7cc48ed 100644 --- a/test/scip/testdata/args.snapshot.rb +++ b/test/scip/testdata/args.snapshot.rb @@ -1,7 +1,7 @@ # typed: true def args(x, y) -#^^^^^^^^^^^^^^ definition [..] Object#args(). +# ^^^^ definition [..] Object#args(). # ^ definition local 1~#2634721084 # ^ definition local 2~#2634721084 z = x + y @@ -25,7 +25,7 @@ def args(x, y) end def keyword_args(w:, x: 3, y: [], **kwargs) -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] Object#keyword_args(). +# ^^^^^^^^^^^^ definition [..] Object#keyword_args(). # ^^ definition local 1~#3526982640 # ^^ definition local 2~#3526982640 # ^^ definition local 3~#3526982640 @@ -39,7 +39,7 @@ def keyword_args(w:, x: 3, y: [], **kwargs) end def use_kwargs -#^^^^^^^^^^^^^^ definition [..] Object#use_kwargs(). +# ^^^^^^^^^^ definition [..] Object#use_kwargs(). h = { a: 3 } # ^ definition local 1~#571973038 keyword_args(w: 0, **h) diff --git a/test/scip/testdata/arrays.snapshot.rb b/test/scip/testdata/arrays.snapshot.rb index 96ab5c7c4..3cb646332 100644 --- a/test/scip/testdata/arrays.snapshot.rb +++ b/test/scip/testdata/arrays.snapshot.rb @@ -1,7 +1,7 @@ # typed: true def arrays(a, i) -#^^^^^^^^^^^^^^^^ definition [..] Object#arrays(). +# ^^^^^^ definition [..] Object#arrays(). # ^ definition local 1~#513334479 # ^ definition local 2~#513334479 a[0] = 0 diff --git a/test/scip/testdata/classes.snapshot.rb b/test/scip/testdata/classes.snapshot.rb index b55719d22..f8deee50b 100644 --- a/test/scip/testdata/classes.snapshot.rb +++ b/test/scip/testdata/classes.snapshot.rb @@ -6,7 +6,7 @@ class C1 # ^^ definition [..] C1# def f() -# ^^^^^^^ definition [..] C1#f(). +# ^ definition [..] C1#f(). _a = C1.new # ^^ definition local 1~#3809224601 # ^^ reference [..] C1# @@ -31,14 +31,14 @@ class M3::C3 end def local_class() -#^^^^^^^^^^^^^^^^^ definition [..] Object#local_class(). +# ^^^^^^^^^^^ definition [..] Object#local_class(). localClass = Class.new # ^^^^^^^^^^ definition local 1~#552113551 # ^^^^^ reference [..] Class# # Technically, this is not supported by Sorbet (https://srb.help/3001), # but make sure we don't crash or do something weird. def localClass.myMethod() -# ^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] Object#myMethod(). +# ^^^^^^^^ definition [..] Object#myMethod(). ":)" end _c = localClass.new @@ -60,7 +60,7 @@ module M4 end def module_access() -#^^^^^^^^^^^^^^^^^^^ definition [..] Object#module_access(). +# ^^^^^^^^^^^^^ definition [..] Object#module_access(). _ = M4::K # ^ definition local 1~#3353511840 # ^^ reference [..] M4# @@ -73,12 +73,12 @@ module M5 module M6 # ^^ definition [..] M5#M6# def self.g() -# ^^^^^^^^^^^^ definition [..] M5#``#g(). +# ^ definition [..] M5#``#g(). end end def self.h() -# ^^^^^^^^^^^^ definition [..] ``#h(). +# ^ definition [..] ``#h(). M6.g() # ^^ reference [..] M5#M6# # ^ reference [..] M5#``#g(). @@ -91,12 +91,12 @@ class C7 module M8 # ^^ definition [..] C7#M8# def self.i() -# ^^^^^^^^^^^^ definition [..] C7#``#i(). +# ^ definition [..] C7#``#i(). end end def j() -# ^^^^^^^ definition [..] C7#j(). +# ^ definition [..] C7#j(). M8.i() # ^^ reference [..] C7#M8# # ^ reference [..] C7#``#i(). diff --git a/test/scip/testdata/def_delegator.snapshot.rb b/test/scip/testdata/def_delegator.snapshot.rb index 7ee110293..23a45e117 100644 --- a/test/scip/testdata/def_delegator.snapshot.rb +++ b/test/scip/testdata/def_delegator.snapshot.rb @@ -5,8 +5,8 @@ class MyArray1 # ^^^^^^^^ definition [..] MyArray1# attr_accessor :inner_array -# ^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] MyArray1#inner_array(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] MyArray1#`inner_array=`(). +# ^^^^^^^^^^^ definition [..] MyArray1#inner_array(). +# ^^^^^^^^^^^ definition [..] MyArray1#`inner_array=`(). extend Forwardable # ^^^^^^^^^^^ reference [..] Forwardable# def_delegator :@inner_array, :[], :get_at_index @@ -30,8 +30,8 @@ class MyArray2 # ^ reference [..] T# # ^^^ reference [..] T#Sig# attr_accessor :inner_array -# ^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] MyArray2#inner_array(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] MyArray2#`inner_array=`(). +# ^^^^^^^^^^^ definition [..] MyArray2#inner_array(). +# ^^^^^^^^^^^ definition [..] MyArray2#`inner_array=`(). extend Forwardable # ^^^^^^^^^^^ reference [..] Forwardable# def_delegator :@inner_array, :[], :get_at_index @@ -52,8 +52,8 @@ class MyArray2 class MyArray3 # ^^^^^^^^ definition [..] MyArray3# attr_accessor :inner_array -# ^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] MyArray3#inner_array(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] MyArray3#`inner_array=`(). +# ^^^^^^^^^^^ definition [..] MyArray3#inner_array(). +# ^^^^^^^^^^^ definition [..] MyArray3#`inner_array=`(). extend Forwardable # ^^^^^^^^^^^ reference [..] Forwardable# def_delegators :@inner_array, :size, :<<, :map @@ -99,8 +99,8 @@ class MyArray4 # ^ reference [..] T# # ^^^ reference [..] T#Sig# attr_accessor :inner_array -# ^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] MyArray4#`inner_array=`(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] MyArray4#inner_array(). +# ^^^^^^^^^^^ definition [..] MyArray4#`inner_array=`(). +# ^^^^^^^^^^^ definition [..] MyArray4#inner_array(). extend Forwardable # ^^^^^^^^^^^ reference [..] Forwardable# def_delegators :@inner_array, :size, :<<, :map diff --git a/test/scip/testdata/fields_and_attrs.snapshot.rb b/test/scip/testdata/fields_and_attrs.snapshot.rb index 188cdec2f..863851472 100644 --- a/test/scip/testdata/fields_and_attrs.snapshot.rb +++ b/test/scip/testdata/fields_and_attrs.snapshot.rb @@ -6,7 +6,7 @@ class K # ^ definition [..] K# def m1 -# ^^^^^^ definition [..] K#m1(). +# ^^ definition [..] K#m1(). @f = 0 # ^^ definition [..] K#`@f`. @g = @f @@ -15,7 +15,7 @@ def m1 return end def m2 -# ^^^^^^ definition [..] K#m2(). +# ^^ definition [..] K#m2(). @f = @g # ^^ definition [..] K#`@f`. # ^^ reference [..] K#`@g`. @@ -27,7 +27,7 @@ def m2 class K # ^ definition [..] K# def m3 -# ^^^^^^ definition [..] K#m3(). +# ^^ definition [..] K#m3(). @g = @f # ^^ definition [..] K#`@g`. # ^^ reference [..] K#`@f`. @@ -43,7 +43,7 @@ class L @y = 9 # ^^ definition [..] ``#`@y`. def self.m1 -# ^^^^^^^^^^^ definition [..] ``#m1(). +# ^^ definition [..] ``#m1(). @y = @x # ^^ definition [..] ``#`@y`. # ^^ reference [..] ``#`@x`. @@ -51,7 +51,7 @@ def self.m1 end def m2 -# ^^^^^^ definition [..] L#m2(). +# ^^ definition [..] L#m2(). # FIXME: Missing references self.class.y = self.class.x return @@ -66,7 +66,7 @@ class N @@b = 1 # ^^^ definition [..] ``#`@@b`. def self.m1 -# ^^^^^^^^^^^ definition [..] ``#m1(). +# ^^ definition [..] ``#m1(). @@b = @@a # ^^^ definition [..] ``#`@@b`. # ^^^ reference [..] ``#`@@a`. @@ -74,7 +74,7 @@ def self.m1 end def m2 -# ^^^^^^ definition [..] N#m2(). +# ^^ definition [..] N#m2(). @@b = @@a # ^^^ definition [..] N#`@@b`. # ^^^ reference [..] N#`@@a`. @@ -82,7 +82,7 @@ def m2 end def m3 -# ^^^^^^ definition [..] N#m3(). +# ^^ definition [..] N#m3(). # FIXME: Missing references self.class.b = self.class.a end @@ -92,15 +92,15 @@ def m3 class P # ^ definition [..] P# attr_accessor :a -# ^^^^^^^^^^^^^^^^ definition [..] P#`a=`(). -# ^^^^^^^^^^^^^^^^ definition [..] P#a(). +# ^ definition [..] P#`a=`(). +# ^ definition [..] P#a(). attr_reader :r -# ^^^^^^^^^^^^^^ definition [..] P#r(). +# ^ definition [..] P#r(). attr_writer :w -# ^^^^^^^^^^^^^^ definition [..] P#`w=`(). +# ^ definition [..] P#`w=`(). def init -# ^^^^^^^^ definition [..] P#init(). +# ^^^^ definition [..] P#init(). self.a = self.r # ^^^ reference [..] P#`a=`(). # ^ reference [..] P#r(). @@ -110,7 +110,7 @@ def init end def wrong_init -# ^^^^^^^^^^^^^^ definition [..] P#wrong_init(). +# ^^^^^^^^^^ definition [..] P#wrong_init(). # Check that 'r' is a method access but 'a' and 'w' are locals a = r # ^ definition local 1~#1021288725 @@ -123,7 +123,7 @@ def wrong_init end def useP -#^^^^^^^^ definition [..] Object#useP(). +# ^^^^ definition [..] Object#useP(). p = P.new # ^ definition local 1~#2121829932 # ^ reference [..] P# diff --git a/test/scip/testdata/for.snapshot.rb b/test/scip/testdata/for.snapshot.rb index 3b275cbff..77446a45f 100644 --- a/test/scip/testdata/for.snapshot.rb +++ b/test/scip/testdata/for.snapshot.rb @@ -1,7 +1,7 @@ # typed: true def for_loop() -#^^^^^^^^^^^^^^ definition [..] Object#for_loop(). +# ^^^^^^^^ definition [..] Object#for_loop(). y = 0 # ^ definition local 1~#1120785331 for x in [1, 2, 3] diff --git a/test/scip/testdata/functions.snapshot.rb b/test/scip/testdata/functions.snapshot.rb index f20793284..76ee7d271 100644 --- a/test/scip/testdata/functions.snapshot.rb +++ b/test/scip/testdata/functions.snapshot.rb @@ -1,7 +1,7 @@ # typed: true def globalFn1() -#^^^^^^^^^^^^^^^ definition [..] Object#globalFn1(). +# ^^^^^^^^^ definition [..] Object#globalFn1(). x = 10 # ^ definition local 1~#3846536873 x @@ -9,7 +9,7 @@ def globalFn1() end def globalFn2() -#^^^^^^^^^^^^^^^ definition [..] Object#globalFn2(). +# ^^^^^^^^^ definition [..] Object#globalFn2(). x = globalFn1() # ^ definition local 1~#3796204016 # ^^^^^^^^^^^^^^^ reference local 1~#3796204016 diff --git a/test/scip/testdata/gem_metadata.snapshot.rb b/test/scip/testdata/gem_metadata.snapshot.rb index e7d229190..8c6e505bc 100644 --- a/test/scip/testdata/gem_metadata.snapshot.rb +++ b/test/scip/testdata/gem_metadata.snapshot.rb @@ -4,12 +4,12 @@ class C # ^ definition leet 1.3.3.7 C# def m -# ^^^^^ definition leet 1.3.3.7 C#m(). +# ^ definition leet 1.3.3.7 C#m(). n # ^ reference leet 1.3.3.7 C#n(). end def n -# ^^^^^ definition leet 1.3.3.7 C#n(). +# ^ definition leet 1.3.3.7 C#n(). m # ^ reference leet 1.3.3.7 C#m(). end diff --git a/test/scip/testdata/hashes.snapshot.rb b/test/scip/testdata/hashes.snapshot.rb index 8a3cb2b5d..376f34347 100644 --- a/test/scip/testdata/hashes.snapshot.rb +++ b/test/scip/testdata/hashes.snapshot.rb @@ -1,7 +1,7 @@ # typed: true def hashes(h, k) -#^^^^^^^^^^^^^^^^ definition [..] Object#hashes(). +# ^^^^^^ definition [..] Object#hashes(). # ^ definition local 1~#1685166589 # ^ definition local 2~#1685166589 h["hello"] = "world" diff --git a/test/scip/testdata/hoverdocs.snapshot.rb b/test/scip/testdata/hoverdocs.snapshot.rb index 06517de90..58a636859 100644 --- a/test/scip/testdata/hoverdocs.snapshot.rb +++ b/test/scip/testdata/hoverdocs.snapshot.rb @@ -15,12 +15,12 @@ class C1 # ^^^ reference [..] T#Sig# def m1 -# ^^^^^^ definition [..] C1#m1(). -# documentation -# | ```ruby -# | sig {returns(T.untyped)} -# | def m1 -# | ``` +# ^^ definition [..] C1#m1(). +# documentation +# | ```ruby +# | sig {returns(T.untyped)} +# | def m1 +# | ``` end sig { returns(T::Boolean) } @@ -30,12 +30,12 @@ def m1 # ^^^^^^^ reference [..] T#Boolean. # ^^^^^^^^^^ reference [..] Sorbet#Private#Static# def m2 -# ^^^^^^ definition [..] C1#m2(). -# documentation -# | ```ruby -# | sig {returns(T::Boolean)} -# | def m2 -# | ``` +# ^^ definition [..] C1#m2(). +# documentation +# | ```ruby +# | sig {returns(T::Boolean)} +# | def m2 +# | ``` true end @@ -50,12 +50,12 @@ def m2 # ^^^^^^^ reference [..] T#Boolean. # ^^^^^^^^^^ reference [..] Sorbet#Private#Static# def m3(c, b) -# ^^^^^^^^^^^^ definition [..] C1#m3(). -# documentation -# | ```ruby -# | sig {params(c: T.untyped, b: T.untyped).returns(T::Boolean)} -# | def m3(c, b) -# | ``` +# ^^ definition [..] C1#m3(). +# documentation +# | ```ruby +# | sig {params(c: T.untyped, b: T.untyped).returns(T::Boolean)} +# | def m3(c, b) +# | ``` # ^ definition local 1~#2519626513 # documentation # | ```ruby @@ -74,15 +74,15 @@ def m3(c, b) # _This_ is a # **doc comment.** def m4(xs) -# ^^^^^^^^^^ definition [..] C1#m4(). -# documentation -# | ```ruby -# | sig {params(xs: T.untyped).returns(T.untyped)} -# | def m4(xs) -# | ``` -# documentation -# | _This_ is a -# | **doc comment.** +# ^^ definition [..] C1#m4(). +# documentation +# | ```ruby +# | sig {params(xs: T.untyped).returns(T.untyped)} +# | def m4(xs) +# | ``` +# documentation +# | _This_ is a +# | **doc comment.** # ^^ definition local 1~#2536404132 # documentation # | ```ruby @@ -101,15 +101,15 @@ def m4(xs) # ^^^^^^^ reference [..] T#Boolean. # ^^^^^^^^^^ reference [..] Sorbet#Private#Static# def m5 -# ^^^^^^ definition [..] C1#m5(). -# documentation -# | ```ruby -# | sig {returns(T::Boolean)} -# | def m5 -# | ``` -# documentation -# | Yet another.. -# | ...doc comment +# ^^ definition [..] C1#m5(). +# documentation +# | ```ruby +# | sig {returns(T::Boolean)} +# | def m5 +# | ``` +# documentation +# | Yet another.. +# | ...doc comment true end @@ -126,15 +126,15 @@ def m5 # ^^^^^^^ reference [..] T#Boolean. # ^^^^^^^^^^ reference [..] Sorbet#Private#Static# def m6(c, b) -# ^^^^^^^^^^^^ definition [..] C1#m6(). -# documentation -# | ```ruby -# | sig {params(c: T.untyped, b: T.untyped).returns(T::Boolean)} -# | def m6(c, b) -# | ``` -# documentation -# | And... -# | ...one more doc comment +# ^^ definition [..] C1#m6(). +# documentation +# | ```ruby +# | sig {params(c: T.untyped, b: T.untyped).returns(T::Boolean)} +# | def m6(c, b) +# | ``` +# documentation +# | And... +# | ...one more doc comment # ^ definition local 1~#2569959370 # documentation # | ```ruby @@ -204,41 +204,41 @@ module M2 # ^^^^^^^ reference [..] T#Boolean. # ^^^^^^^^^^ reference [..] Sorbet#Private#Static# def n1 -# ^^^^^^ definition [..] M1#M2#n1(). -# documentation -# | ```ruby -# | sig {returns(T::Boolean)} -# | def n1 -# | ``` -# documentation -# | This method is inside M1::M2 +# ^^ definition [..] M1#M2#n1(). +# documentation +# | ```ruby +# | sig {returns(T::Boolean)} +# | def n1 +# | ``` +# documentation +# | This method is inside M1::M2 true end # This method is also inside M1::M2 def n2 -# ^^^^^^ definition [..] M1#M2#n2(). -# documentation -# | ```ruby -# | sig {returns(T.untyped)} -# | def n2 -# | ``` -# documentation -# | This method is also inside M1::M2 +# ^^ definition [..] M1#M2#n2(). +# documentation +# | ```ruby +# | sig {returns(T.untyped)} +# | def n2 +# | ``` +# documentation +# | This method is also inside M1::M2 end end end # This is a global function def f1 -#^^^^^^ definition [..] Object#f1(). -#documentation -#| ```ruby -#| sig {returns(T.untyped)} -#| def f1 -#| ``` -#documentation -#| This is a global function +# ^^ definition [..] Object#f1(). +# documentation +# | ```ruby +# | sig {returns(T.untyped)} +# | def f1 +# | ``` +# documentation +# | This is a global function M1::M2::m6 # ^^ reference [..] M1# # ^^ reference [..] M1#M2# @@ -255,24 +255,24 @@ def f1 # ^^^^^^^ reference [..] `T.untyped`# # ^^^^^^^^^^ reference [..] Sorbet#Private#Static# def f2 -#^^^^^^ definition [..] Object#f2(). -#documentation -#| ```ruby -#| sig {returns(T::Integer (unresolved))} -#| def f2 -#| ``` -#documentation -#| Yet another global function +# ^^ definition [..] Object#f2(). +# documentation +# | ```ruby +# | sig {returns(T::Integer (unresolved))} +# | def f2 +# | ``` +# documentation +# | Yet another global function return 10 end def f3 # undocumented global function -#^^^^^^ definition [..] Object#f3(). -#documentation -#| ```ruby -#| sig {returns(T.untyped)} -#| def f3 -#| ``` +# ^^ definition [..] Object#f3(). +# documentation +# | ```ruby +# | sig {returns(T.untyped)} +# | def f3 +# | ``` end extend T::Sig @@ -286,12 +286,12 @@ def f3 # undocumented global function # ^^^^^^^ reference [..] `T.untyped`# # ^^^^^^^^^^ reference [..] Sorbet#Private#Static# def f4 # another undocumented global function -#^^^^^^ definition [..] Object#f4(). -#documentation -#| ```ruby -#| sig {returns(T::Integer (unresolved))} -#| def f4 -#| ``` +# ^^ definition [..] Object#f4(). +# documentation +# | ```ruby +# | sig {returns(T::Integer (unresolved))} +# | def f4 +# | ``` return 10 end @@ -306,14 +306,14 @@ class K1 # | Parent class # sets @x and @@y def p1 -# ^^^^^^ definition [..] K1#p1(). -# documentation -# | ```ruby -# | sig {returns(T.untyped)} -# | def p1 -# | ``` -# documentation -# | sets @x and @@y +# ^^ definition [..] K1#p1(). +# documentation +# | ```ruby +# | sig {returns(T.untyped)} +# | def p1 +# | ``` +# documentation +# | sets @x and @@y @x = 10 # ^^ definition [..] K1#`@x`. # documentation @@ -335,14 +335,14 @@ def p1 # lorem ipsum, you get it def self.p2 -# ^^^^^^^^^^^ definition [..] ``#p2(). -# documentation -# | ```ruby -# | sig {returns(T.untyped)} -# | def self.p2 -# | ``` -# documentation -# | lorem ipsum, you get it +# ^^ definition [..] ``#p2(). +# documentation +# | ```ruby +# | sig {returns(T.untyped)} +# | def self.p2 +# | ``` +# documentation +# | lorem ipsum, you get it @z = 10 # ^^ definition [..] ``#`@z`. # documentation @@ -385,14 +385,14 @@ class K2 < K1 # overrides K1's p1 def p1 -# ^^^^^^ definition [..] K2#p1(). -# documentation -# | ```ruby -# | sig {returns(T.untyped)} -# | def p1 -# | ``` -# documentation -# | overrides K1's p1 +# ^^ definition [..] K2#p1(). +# documentation +# | ```ruby +# | sig {returns(T.untyped)} +# | def p1 +# | ``` +# documentation +# | overrides K1's p1 @x = 20 # ^^ definition [..] K2#`@x`. # documentation diff --git a/test/scip/testdata/implicit_super_arg.snapshot.rb b/test/scip/testdata/implicit_super_arg.snapshot.rb index 352c88b9d..003672d3b 100644 --- a/test/scip/testdata/implicit_super_arg.snapshot.rb +++ b/test/scip/testdata/implicit_super_arg.snapshot.rb @@ -21,7 +21,7 @@ class C # ^ definition [..] C# def f(a, b) -# ^^^^^^^^^^^ definition [..] C#f(). +# ^ definition [..] C#f(). # ^ definition local 1~#3809224601 # ^ definition local 2~#3809224601 super diff --git a/test/scip/testdata/inheritance.snapshot.rb b/test/scip/testdata/inheritance.snapshot.rb index 9bbdc70d8..13399dc3e 100644 --- a/test/scip/testdata/inheritance.snapshot.rb +++ b/test/scip/testdata/inheritance.snapshot.rb @@ -14,7 +14,7 @@ class Z1 # ^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# # ^^^^ reference [..] T#Private#Methods#DeclBuilder#void(). def write_f(a) -# ^^^^^^^^^^^^^^ definition [..] Z1#write_f(). +# ^^^^^^^ definition [..] Z1#write_f(). # ^ definition local 1~#1000661517 @f = a # ^^ definition [..] Z1#`@f`. @@ -29,7 +29,7 @@ def write_f(a) # ^^^^^^^ reference [..] T#Boolean. # ^^^^^^^^^^ reference [..] Sorbet#Private#Static# def read_f? -# ^^^^^^^^^^^ definition [..] Z1#`read_f?`(). +# ^^^^^^^ definition [..] Z1#`read_f?`(). @f # ^^ reference [..] Z1#`@f`. end @@ -48,7 +48,7 @@ class Z2 # ^^^^^^^ reference [..] T#Boolean. # ^^^^^^^^^^ reference [..] Sorbet#Private#Static# def read_f? -# ^^^^^^^^^^^ definition [..] Z2#`read_f?`(). +# ^^^^^^^ definition [..] Z2#`read_f?`(). @f # ^^ reference [..] Z2#`@f`. end @@ -61,7 +61,7 @@ def read_f? # ^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# # ^^^^ reference [..] T#Private#Methods#DeclBuilder#void(). def write_f(a) -# ^^^^^^^^^^^^^^ definition [..] Z2#write_f(). +# ^^^^^^^ definition [..] Z2#write_f(). # ^ definition local 1~#1000661517 @f = a # ^^ definition [..] Z2#`@f`. @@ -84,7 +84,7 @@ class Z3 < Z1 # ^^^^^^^ reference [..] T#Boolean. # ^^^^^^^^^^ reference [..] Sorbet#Private#Static# def read_f_plus_1? -# ^^^^^^^^^^^^^^^^^^ definition [..] Z3#`read_f_plus_1?`(). +# ^^^^^^^^^^^^^^ definition [..] Z3#`read_f_plus_1?`(). @f + 1 # ^^ reference [..] Z3#`@f`. end @@ -105,7 +105,7 @@ class Z4 < Z3 # ^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# # ^^^^ reference [..] T#Private#Methods#DeclBuilder#void(). def write_f_plus_1(a) -# ^^^^^^^^^^^^^^^^^^^^^ definition [..] Z4#write_f_plus_1(). +# ^^^^^^^^^^^^^^ definition [..] Z4#write_f_plus_1(). # ^ definition local 1~#3337417690 write_f(a) # ^ reference local 1~#3337417690 diff --git a/test/scip/testdata/loops_and_conditionals.snapshot.rb b/test/scip/testdata/loops_and_conditionals.snapshot.rb index 24cc13e11..4a872437c 100644 --- a/test/scip/testdata/loops_and_conditionals.snapshot.rb +++ b/test/scip/testdata/loops_and_conditionals.snapshot.rb @@ -1,7 +1,7 @@ # typed: true def if_elsif_else() -#^^^^^^^^^^^^^^^^^^^ definition [..] Object#if_elsif_else(). +# ^^^^^^^^^^^^^ definition [..] Object#if_elsif_else(). x = 0 # ^ definition local 1~#2393773952 y = 0 @@ -44,7 +44,7 @@ def if_elsif_else() end def unless() -#^^^^^^^^^^^^ definition [..] Object#unless(). +# ^^^^^^ definition [..] Object#unless(). z = 0 # ^ definition local 1~#2827997891 x = 1 @@ -67,7 +67,7 @@ def unless() end def case(x, y) -#^^^^^^^^^^^^^^ definition [..] Object#case(). +# ^^^^ definition [..] Object#case(). # ^ definition local 1~#2602907825 # ^ definition local 2~#2602907825 case x @@ -92,7 +92,7 @@ def case(x, y) end def for(xs) -#^^^^^^^^^^^ definition [..] Object#for(). +# ^^^ definition [..] Object#for(). # ^^ definition local 1~#2901640080 for e in xs # ^ definition local 2~#2901640080 @@ -125,7 +125,7 @@ def for(xs) end def while(xs) -#^^^^^^^^^^^^^ definition [..] Object#while(). +# ^^^^^ definition [..] Object#while(). # ^^ definition local 1~#231090382 i = 0 # ^ definition local 2~#231090382 @@ -162,7 +162,7 @@ def while(xs) end def until(xs) -#^^^^^^^^^^^^^ definition [..] Object#until(). +# ^^^^^ definition [..] Object#until(). # ^^ definition local 1~#3132432719 i = 0 # ^ definition local 2~#3132432719 @@ -199,7 +199,7 @@ def until(xs) end def flip_flop(xs) -#^^^^^^^^^^^^^^^^^ definition [..] Object#flip_flop(). +# ^^^^^^^^^ definition [..] Object#flip_flop(). # ^^ definition local 1~#2191960030 # NOTE: flip-flops are unsupported (https://srb.help/3003) # Unlike redo, which somehow works, we fail to emit references diff --git a/test/scip/testdata/multifile/basic/def_class1.snapshot.rb b/test/scip/testdata/multifile/basic/def_class1.snapshot.rb index 84e94e317..3ac78ff8e 100644 --- a/test/scip/testdata/multifile/basic/def_class1.snapshot.rb +++ b/test/scip/testdata/multifile/basic/def_class1.snapshot.rb @@ -13,7 +13,7 @@ class C1 # ^^^^^^^ reference [..] T#Boolean. # ^^^^^^^^^^ reference [..] Sorbet#Private#Static# def m1 -# ^^^^^^ definition [..] C1#m1(). +# ^^ definition [..] C1#m1(). true end end diff --git a/test/scip/testdata/rescue.snapshot.rb b/test/scip/testdata/rescue.snapshot.rb index 7e7a7cba5..c2102e69f 100644 --- a/test/scip/testdata/rescue.snapshot.rb +++ b/test/scip/testdata/rescue.snapshot.rb @@ -6,14 +6,14 @@ class MyError < StandardError end def handle(e) -#^^^^^^^^^^^^^ definition [..] Object#handle(). +# ^^^^^^ definition [..] Object#handle(). # ^ definition local 1~#780127187 puts e.inspect.to_s # ^ reference local 1~#780127187 end def f -#^^^^^ definition [..] Object#f(). +# ^ definition [..] Object#f(). begin raise 'This exception will be rescued!' rescue MyError => e1 diff --git a/test/scip/testdata/struct.snapshot.rb b/test/scip/testdata/struct.snapshot.rb index 3465473e9..b4da21e14 100644 --- a/test/scip/testdata/struct.snapshot.rb +++ b/test/scip/testdata/struct.snapshot.rb @@ -18,8 +18,8 @@ class S < T::Struct # ^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). # ^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). # ^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# -# ^^^^^^^^^^^^^^^^^^^^^ definition [..] S#`prop_i=`(). -# ^^^^^^^^^^^^^^^^^^^^^ definition [..] S#prop_i(). +# ^^^^^^ definition [..] S#`prop_i=`(). +# ^^^^^^ definition [..] S#prop_i(). # ^^^^^^^ reference [..] Integer# # ^^^^^^^ reference [..] Integer# # ^^^^^^^ reference [..] Integer# @@ -29,7 +29,7 @@ class S < T::Struct # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] S#const_s(). +# ^^^^^^^ definition [..] S#const_s(). # ^ reference [..] T# # ^ reference [..] T# # ^ reference [..] T# @@ -41,16 +41,16 @@ class S < T::Struct # ^^^^^^ reference [..] String# const :const_f, Float, default: 0.5 # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] S#const_f(). # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# +# ^^^^^^^ definition [..] S#const_f(). # ^^^^^ reference [..] Float# # ^^^^^ reference [..] Float# # ^^^^^ reference [..] Float# end def f -#^^^^^ definition [..] Object#f(). +# ^ definition [..] Object#f(). s = S.new(prop_i: 3) # ^ definition local 1~#3809224601 # ^ reference [..] S# @@ -92,7 +92,7 @@ def f # ^ definition [..] POINT#`y=`(). # ^ reference [..] BasicObject# def array -# ^^^^^^^^^ definition [..] POINT#array(). +# ^^^^^ definition [..] POINT#array(). [x, y] # ^ reference [..] POINT#x(). # ^ reference [..] POINT#y(). @@ -100,7 +100,7 @@ def array end def g -#^^^^^ definition [..] Object#g(). +# ^ definition [..] Object#g(). p = POINT.new(0, 1) # ^ definition local 1~#3792446982 # ^^^^^ reference [..] POINT# diff --git a/test/scip/testdata/type_change.snapshot.rb b/test/scip/testdata/type_change.snapshot.rb index b446852ed..490bf10cf 100644 --- a/test/scip/testdata/type_change.snapshot.rb +++ b/test/scip/testdata/type_change.snapshot.rb @@ -2,12 +2,12 @@ # options: showDocs def assign_different_branches(b) -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] Object#assign_different_branches(). -#documentation -#| ```ruby -#| sig {params(b: T.untyped).returns(T.untyped)} -#| def assign_different_branches(b) -#| ``` +# ^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] Object#assign_different_branches(). +# documentation +# | ```ruby +# | sig {params(b: T.untyped).returns(T.untyped)} +# | def assign_different_branches(b) +# | ``` # ^ definition local 1~#3317016627 # documentation # | ```ruby @@ -32,12 +32,12 @@ def assign_different_branches(b) end def change_different_branches(b) -#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] Object#change_different_branches(). -#documentation -#| ```ruby -#| sig {params(b: T.untyped).returns(T.untyped)} -#| def change_different_branches(b) -#| ``` +# ^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] Object#change_different_branches(). +# documentation +# | ```ruby +# | sig {params(b: T.untyped).returns(T.untyped)} +# | def change_different_branches(b) +# | ``` # ^ definition local 1~#2122680152 # documentation # | ```ruby @@ -68,12 +68,12 @@ def change_different_branches(b) end def loop_type_change(bs) -#^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] Object#loop_type_change(). -#documentation -#| ```ruby -#| sig {params(bs: T.untyped).returns(T.untyped)} -#| def loop_type_change(bs) -#| ``` +# ^^^^^^^^^^^^^^^^ definition [..] Object#loop_type_change(). +# documentation +# | ```ruby +# | sig {params(bs: T.untyped).returns(T.untyped)} +# | def loop_type_change(bs) +# | ``` # ^^ definition local 1~#4057334513 # documentation # | ```ruby @@ -137,12 +137,12 @@ class C # | ``` def change_type(b) -# ^^^^^^^^^^^^^^^^^^ definition [..] C#change_type(). -# documentation -# | ```ruby -# | sig {params(b: T.untyped).returns(T.untyped)} -# | def change_type(b) -# | ``` +# ^^^^^^^^^^^ definition [..] C#change_type(). +# documentation +# | ```ruby +# | sig {params(b: T.untyped).returns(T.untyped)} +# | def change_type(b) +# | ``` # ^ definition local 1~#2066187318 # documentation # | ```ruby @@ -230,12 +230,12 @@ class D < C # | class C # | ``` def change_type(b) -# ^^^^^^^^^^^^^^^^^^ definition [..] D#change_type(). -# documentation -# | ```ruby -# | sig {params(b: T.untyped).returns(T.untyped)} -# | def change_type(b) -# | ``` +# ^^^^^^^^^^^ definition [..] D#change_type(). +# documentation +# | ```ruby +# | sig {params(b: T.untyped).returns(T.untyped)} +# | def change_type(b) +# | ``` # ^ definition local 1~#2066187318 # documentation # | ```ruby diff --git a/test/scip/testdata/type_docs.snapshot.rb b/test/scip/testdata/type_docs.snapshot.rb index 0062e2e8b..d239c7502 100644 --- a/test/scip/testdata/type_docs.snapshot.rb +++ b/test/scip/testdata/type_docs.snapshot.rb @@ -18,12 +18,12 @@ module M # ^^^^^^ reference [..] String# # ^^^^^^ reference [..] String# def js_add(x, y) -# ^^^^^^^^^^^^^^^^ definition [..] M#js_add(). -# documentation -# | ```ruby -# | sig {params(x: Integer, y: String).returns(String)} -# | def js_add(x, y) -# | ``` +# ^^^^^^ definition [..] M#js_add(). +# documentation +# | ```ruby +# | sig {params(x: Integer, y: String).returns(String)} +# | def js_add(x, y) +# | ``` # ^ definition local 1~#1239553962 # documentation # | ```ruby diff --git a/test/scip/testdata/types.snapshot.rb b/test/scip/testdata/types.snapshot.rb index ce065a835..276c580ae 100644 --- a/test/scip/testdata/types.snapshot.rb +++ b/test/scip/testdata/types.snapshot.rb @@ -1,7 +1,7 @@ # typed: true def f() -#^^^^^^^ definition [..] Object#f(). +# ^ definition [..] Object#f(). T.let(true, T::Boolean) # ^ reference [..] T# # ^^^^^^^ reference [..] T#Boolean. @@ -19,8 +19,8 @@ module M # ^^^^^^^^^^ reference [..] Sorbet#Private#Static# # ^^^^^^^^^^ reference [..] Sorbet#Private#Static# def b -# ^^^^^ definition [..] M#b(). -# ^^^^^ definition [..] ``#b(). +# ^ definition [..] M#b(). +# ^ definition [..] ``#b(). true end end From 2ff521a08bf496260c3d4d8d1c7d77ae302c44cf Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Mon, 5 Sep 2022 18:31:58 +0800 Subject: [PATCH 03/19] cleanup: Move formatting function to core::Loc for reuse. --- cfg/CFG.cc | 17 ++++------------- core/Loc.cc | 12 ++++++++++++ core/Loc.h | 1 + 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/cfg/CFG.cc b/cfg/CFG.cc index 621da7df1..0eea3a5a3 100644 --- a/cfg/CFG.cc +++ b/cfg/CFG.cc @@ -238,25 +238,16 @@ string CFG::toString(const core::GlobalState &gs) const { return to_string(buf); } -string locToString(const core::GlobalState &gs, core::Loc loc) { - if (!loc.exists() || loc.empty()) { - return " @ <>"; - } - auto [start, end] = loc.position(gs); - return start.line == end.line ? fmt::format(" @ {}:{}-{}", start.line, start.column, end.column) - : fmt::format(" @ {}:{}-{}:{}", start.line, start.column, end.line, end.column); -} - string CFG::toTextualString(const core::GlobalState &gs, optional file) const { fmt::memory_buffer buf; string symbolName = this->symbol.showFullName(gs); if (file) { auto method = this->symbol.data(gs); if (method->nameLoc.exists() && !method->nameLoc.empty()) { - fmt::format_to(std::back_inserter(buf), "method{} {} {{\n\n", - locToString(gs, core::Loc(file.value(), method->nameLoc)), symbolName); + fmt::format_to(std::back_inserter(buf), "method @ {} {} {{\n\n", + core::Loc(file.value(), method->nameLoc).showRawLineColumn(gs), symbolName); } else { - fmt::format_to(std::back_inserter(buf), "method{} (full) {} {{\n\n", locToString(gs, method->loc()), + fmt::format_to(std::back_inserter(buf), "method @ {} (full) {} {{\n\n", method->loc().showRawLineColumn(gs), symbolName); } } else { @@ -399,7 +390,7 @@ string BasicBlock::toTextualString(const core::GlobalState &gs, optionalexprs) { string positionText = ""; if (file) { - positionText = locToString(gs, core::Loc(file.value(), exp.loc)); + positionText = fmt::format(" @ {}", core::Loc(file.value(), exp.loc).showRawLineColumn(gs)); } fmt::format_to(std::back_inserter(buf), " {}{} = {}\n", exp.bind.toString(gs, cfg), positionText, diff --git a/core/Loc.cc b/core/Loc.cc index 875eebaff..65bc07789 100644 --- a/core/Loc.cc +++ b/core/Loc.cc @@ -235,6 +235,18 @@ string Loc::showRaw(const GlobalState &gs) const { return fmt::format("Loc {{file={} start={}:{} end={}:{}}}", path, start.line, start.column, end.line, end.column); } +string Loc::showRawLineColumn(const core::GlobalState &gs) const { + if (!this->exists()) { + return "<>"; + } + if (this->empty()) { + return "<_>"; + } + auto [start, end] = this->position(gs); + return start.line == end.line ? fmt::format("{}:{}-{}", start.line, start.column, end.column) + : fmt::format("{}:{}-{}:{}", start.line, start.column, end.line, end.column); +} + string Loc::filePosToString(const GlobalState &gs, bool showFull) const { stringstream buf; if (!file().exists()) { diff --git a/core/Loc.h b/core/Loc.h index 5a2c5cec3..ff40b76ba 100644 --- a/core/Loc.h +++ b/core/Loc.h @@ -99,6 +99,7 @@ class Loc final { return toStringWithTabs(gs); } std::string showRaw(const GlobalState &gs) const; + std::string showRawLineColumn(const GlobalState &gs) const; std::string filePosToString(const GlobalState &gs, bool showFull = false) const; std::optional source(const GlobalState &gs) const; From a6904da37106b6c599718cef0d3eac2ca0098f95 Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Mon, 5 Sep 2022 18:43:53 +0800 Subject: [PATCH 04/19] fix: Fix source locations for def_delegator. --- rewriter/DefDelegator.cc | 10 +++++--- test/scip/testdata/def_delegator.snapshot.rb | 26 ++++++++++---------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/rewriter/DefDelegator.cc b/rewriter/DefDelegator.cc index 94cbb927c..55e70bb27 100644 --- a/rewriter/DefDelegator.cc +++ b/rewriter/DefDelegator.cc @@ -9,7 +9,7 @@ using namespace std; namespace sorbet::rewriter { /// Generate method stub and sig for the delegator method -void generateStub(vector &methodStubs, const core::LocOffsets &loc, +void generateStub(vector &methodStubs, const core::LocOffsets &loc, core::LocOffsets nameLoc, const core::NameRef &methodName) { // sig {params(arg0: T.untyped, blk: Proc).returns(T.untyped)} auto sigArgs = ast::MK::SendArgs(ast::MK::Symbol(loc, core::Names::arg0()), ast::MK::Untyped(loc), @@ -24,7 +24,7 @@ void generateStub(vector &methodStubs, const core::LocOffset args.emplace_back(ast::make_expression(loc, ast::MK::Local(loc, core::Names::blkArg()))); methodStubs.push_back( - ast::MK::SyntheticMethod(loc, loc, loc, methodName, std::move(args), ast::MK::RaiseUnimplemented(loc))); + ast::MK::SyntheticMethod(loc, loc, nameLoc, methodName, std::move(args), ast::MK::RaiseUnimplemented(loc))); } /// Handle #def_delegator for a single delegate method @@ -53,6 +53,7 @@ vector runDefDelegator(core::MutableContext ctx, const ast:: } core::NameRef methodName = method->asSymbol(); + auto nameLoc = method->loc; if (send->numPosArgs() == 3) { auto *alias = ast::cast_tree(send->getPosArg(2)); @@ -61,9 +62,10 @@ vector runDefDelegator(core::MutableContext ctx, const ast:: } methodName = alias->asSymbol(); + nameLoc = alias->loc; } - generateStub(methodStubs, loc, methodName); + generateStub(methodStubs, loc, nameLoc, methodName); // Include the original call to def_delegator so sorbet will still type-check it // and throw errors if the class (or its parent) didn't `extend Forwardable` @@ -100,7 +102,7 @@ vector runDefDelegators(core::MutableContext ctx, const ast: continue; } - generateStub(methodStubs, loc, method->asSymbol()); + generateStub(methodStubs, loc, method->loc, method->asSymbol()); } // Include the original call to def_delegators so sorbet will still type-check it diff --git a/test/scip/testdata/def_delegator.snapshot.rb b/test/scip/testdata/def_delegator.snapshot.rb index 23a45e117..32c11a421 100644 --- a/test/scip/testdata/def_delegator.snapshot.rb +++ b/test/scip/testdata/def_delegator.snapshot.rb @@ -10,7 +10,6 @@ class MyArray1 extend Forwardable # ^^^^^^^^^^^ reference [..] Forwardable# def_delegator :@inner_array, :[], :get_at_index -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] MyArray1#get_at_index(). # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# @@ -22,6 +21,7 @@ class MyArray1 # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Proc# +# ^^^^^^^^^^^^^ definition [..] MyArray1#get_at_index(). end class MyArray2 @@ -35,7 +35,6 @@ class MyArray2 extend Forwardable # ^^^^^^^^^^^ reference [..] Forwardable# def_delegator :@inner_array, :[], :get_at_index -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] MyArray2#get_at_index(). # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# @@ -47,6 +46,7 @@ class MyArray2 # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Proc# +# ^^^^^^^^^^^^^ definition [..] MyArray2#get_at_index(). end class MyArray3 @@ -58,15 +58,15 @@ class MyArray3 # ^^^^^^^^^^^ reference [..] Forwardable# def_delegators :@inner_array, :size, :<<, :map # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#nilable(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Proc# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] MyArray3#map(). # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#nilable(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] MyArray3#`<<`(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). @@ -75,7 +75,7 @@ class MyArray3 # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] MyArray3#size(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). @@ -85,12 +85,12 @@ class MyArray3 # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#nilable(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#nilable(). +# ^^^^^ definition [..] MyArray3#size(). +# ^^^ definition [..] MyArray3#`<<`(). +# ^^^^ definition [..] MyArray3#map(). end class MyArray4 @@ -104,8 +104,8 @@ class MyArray4 extend Forwardable # ^^^^^^^^^^^ reference [..] Forwardable# def_delegators :@inner_array, :size, :<<, :map -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] MyArray4#size(). # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Proc# +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# @@ -134,8 +134,8 @@ class MyArray4 # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] MyArray4#map(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] MyArray4#`<<`(). # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). +# ^^^^^ definition [..] MyArray4#size(). +# ^^^ definition [..] MyArray4#`<<`(). +# ^^^^ definition [..] MyArray4#map(). end From f499313dea612883902cadd24193c58aca9004cb Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Mon, 5 Sep 2022 19:49:31 +0800 Subject: [PATCH 05/19] cleanup: Remove some TODOs and add a named FIXME for aliases. --- class_flatten/class_flatten.cc | 7 +++---- core/GlobalState.cc | 4 +--- resolver/resolver.cc | 5 +++-- test/scip/testdata/alias.rb | 14 ++++++++++++++ test/scip/testdata/alias.snapshot.rb | 19 +++++++++++++++++++ 5 files changed, 40 insertions(+), 9 deletions(-) create mode 100644 test/scip/testdata/alias.rb create mode 100644 test/scip/testdata/alias.snapshot.rb diff --git a/class_flatten/class_flatten.cc b/class_flatten/class_flatten.cc index ff1d17b0c..df7c78917 100644 --- a/class_flatten/class_flatten.cc +++ b/class_flatten/class_flatten.cc @@ -111,10 +111,9 @@ class ClassFlattenWalk { ast::MethodDef::ARGS_store args; args.emplace_back(ast::make_expression(blkLoc, blkLocalVar)); - // TODO(varun): What does classDef->declLoc correspond to? - auto init = ast::make_expression(classDef->declLoc, classDef->declLoc, classDef->declLoc, sym, - core::Names::staticInit(), std::move(args), std::move(inits), - ast::MethodDef::Flags()); + auto init = ast::make_expression(classDef->declLoc, classDef->declLoc, core::LocOffsets::none(), + sym, core::Names::staticInit(), std::move(args), + std::move(inits), ast::MethodDef::Flags()); ast::cast_tree_nonnull(init).flags.isRewriterSynthesized = false; ast::cast_tree_nonnull(init).flags.isSelfMethod = true; diff --git a/core/GlobalState.cc b/core/GlobalState.cc index a11b7daee..594d592c2 100644 --- a/core/GlobalState.cc +++ b/core/GlobalState.cc @@ -1725,8 +1725,6 @@ void GlobalState::mangleRenameSymbolInternal(SymbolRef what, NameRef origName, U } case SymbolRef::Kind::Method: what.asMethodRef().data(*this)->name = name; - // TODO(varun): This code path seems to be triggered when processing the stdlib. - // Should we be setting nameLoc here? break; case SymbolRef::Kind::FieldOrStaticField: what.asFieldRef().data(*this)->name = name; @@ -2347,7 +2345,7 @@ const vector> &GlobalState::getFiles() const { MethodRef GlobalState::staticInitForClass(ClassOrModuleRef klass, Loc loc) { auto prevCount = methodsUsed(); auto sym = enterMethodSymbol(loc, klass.data(*this)->singletonClass(*this), core::Names::staticInit(), - klass.data(*this)->loc().offsets()); // TODO(varun): Check if this is OK + klass.data(*this)->loc().offsets()); if (prevCount != methodsUsed()) { auto blkLoc = core::Loc::none(loc.file()); auto &blkSym = enterMethodArgumentSymbol(blkLoc, sym, core::Names::blkArg()); diff --git a/resolver/resolver.cc b/resolver/resolver.cc index 624f332d0..381edda7c 100644 --- a/resolver/resolver.cc +++ b/resolver/resolver.cc @@ -1874,6 +1874,7 @@ class ResolveTypeMembersAndFieldsWalk { core::ClassOrModuleRef owner; core::LocOffsets loc; core::LocOffsets toNameLoc; + // FIXME[alias-support]: Add a fromNameLoc field here core::NameRef toName; core::NameRef fromName; }; @@ -2439,8 +2440,8 @@ class ResolveTypeMembersAndFieldsWalk { return; } - // TODO(varun): is toNameLoc the right field? - auto alias = ctx.state.enterMethodSymbol(ctx.locAt(job.loc), job.owner, job.fromName, job.toNameLoc); + // FIXME[alias-support]: Use job.fromNameLoc here for the last argument. + auto alias = ctx.state.enterMethodSymbol(ctx.locAt(job.loc), job.owner, job.fromName, job.loc); alias.data(ctx)->resultType = core::make_type(core::SymbolRef(toMethod)); // Add a fake keyword argument to remember the toName (for fast path hashing). diff --git a/test/scip/testdata/alias.rb b/test/scip/testdata/alias.rb new file mode 100644 index 000000000..c8cec4665 --- /dev/null +++ b/test/scip/testdata/alias.rb @@ -0,0 +1,14 @@ +# typed: true + +class X + alias_method :am_aaa, :aaa + alias :a_aaa :aaa + + def aaa + puts "AAA" + end + + def check_alias + return [am_aaa, a_aaa] + end +end diff --git a/test/scip/testdata/alias.snapshot.rb b/test/scip/testdata/alias.snapshot.rb new file mode 100644 index 000000000..b68c3fbbc --- /dev/null +++ b/test/scip/testdata/alias.snapshot.rb @@ -0,0 +1,19 @@ + # typed: true + + class X +# ^ definition [..] X# + alias_method :am_aaa, :aaa + alias :a_aaa :aaa + + def aaa +# ^^^ definition [..] X#aaa(). + puts "AAA" + end + + def check_alias +# ^^^^^^^^^^^ definition [..] X#check_alias(). + return [am_aaa, a_aaa] +# ^^^^^^ reference [..] X#am_aaa(). +# ^^^^^ reference [..] X#a_aaa(). + end + end From 8a4c034d3468e66f8e56bb5ed9f50ff654ba4a7b Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Mon, 5 Sep 2022 20:00:21 +0800 Subject: [PATCH 06/19] cleanup: Fix some source locations + remove debug print statements. --- rewriter/Command.cc | 4 ++-- rewriter/DSLBuilder.cc | 9 +++------ rewriter/Prop.cc | 2 -- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/rewriter/Command.cc b/rewriter/Command.cc index 64392295a..05db336cc 100644 --- a/rewriter/Command.cc +++ b/rewriter/Command.cc @@ -84,8 +84,8 @@ void Command::run(core::MutableContext ctx, ast::ClassDef *klass) { ast::MethodDef::Flags flags; flags.isSelfMethod = true; flags.discardDef = true; - auto selfCall = ast::MK::SyntheticMethod(call->loc, call->loc, call->loc, call->name, std::move(newArgs), - ast::MK::UntypedNil(call->loc), flags); + auto selfCall = ast::MK::SyntheticMethod(call->loc, call->loc, core::LocOffsets::none(), call->name, + std::move(newArgs), ast::MK::UntypedNil(call->loc), flags); klass->rhs.insert(klass->rhs.begin() + i + 1, sig->deepCopy()); klass->rhs.insert(klass->rhs.begin() + i + 2, std::move(selfCall)); diff --git a/rewriter/DSLBuilder.cc b/rewriter/DSLBuilder.cc index 40106a34c..15203a5ce 100644 --- a/rewriter/DSLBuilder.cc +++ b/rewriter/DSLBuilder.cc @@ -53,8 +53,6 @@ vector DSLBuilder::run(core::MutableContext ctx, ast::Send * ENFORCE(!ctx.locAt(sym->loc).source(ctx).value().empty() && ctx.locAt(sym->loc).source(ctx).value()[0] == ':'); auto nameLoc = core::LocOffsets{sym->loc.beginPos() + 1, sym->loc.endPos()}; - fmt::print(stderr, "log: [DSLBuilder::run] name = {} @ {}\n", name.toString(ctx), ctx.locAt(nameLoc).showRaw(ctx)); - type = ASTUtil::dupType(send->getPosArg(1)); if (!type) { return empty; @@ -108,16 +106,15 @@ vector DSLBuilder::run(core::MutableContext ctx, ast::Send * // def self.get_ core::NameRef getName = ctx.state.enterNameUTF8("get_" + name.show(ctx)); stats.emplace_back(ast::MK::Sig0(loc, ASTUtil::dupType(type))); - // TODO(varun): Get proper location here auto defSelfGetProp = - ast::MK::SyntheticMethod(loc, loc, loc, getName, {}, ast::MK::RaiseUnimplemented(loc), flags); + ast::MK::SyntheticMethod(loc, loc, nameLoc, getName, {}, ast::MK::RaiseUnimplemented(loc), flags); ast::cast_tree(defSelfGetProp)->flags.isSelfMethod = true; stats.emplace_back(move(defSelfGetProp)); - // TODO(varun): Get proper location here // def () stats.emplace_back(ast::MK::Sig0(loc, ASTUtil::dupType(type))); - stats.emplace_back(ast::MK::SyntheticMethod(loc, loc, loc, name, {}, ast::MK::RaiseUnimplemented(loc), flags)); + stats.emplace_back( + ast::MK::SyntheticMethod(loc, loc, nameLoc, name, {}, ast::MK::RaiseUnimplemented(loc), flags)); } return stats; diff --git a/rewriter/Prop.cc b/rewriter/Prop.cc index e0acd95ef..6cb729b29 100644 --- a/rewriter/Prop.cc +++ b/rewriter/Prop.cc @@ -353,8 +353,6 @@ vector processProp(core::MutableContext ctx, PropInfo &ret, const auto name = ret.name; const auto nameLoc = ret.nameLoc; - fmt::print(stderr, "log: [processProp] name = {} @ {}\n", name.toString(ctx), ctx.locAt(nameLoc).showRaw(ctx)); - const auto getType = ASTUtil::dupType(ret.type); const auto computedByMethodName = ret.computedByMethodName; From 1e99c8f7ade62cf1da45947754dc0b64d273eec2 Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Mon, 5 Sep 2022 20:25:24 +0800 Subject: [PATCH 07/19] fix: Fix source locations for delegate. --- rewriter/Delegate.cc | 3 +- test/scip/testdata/delegate.rb | 17 +++++ test/scip/testdata/delegate.snapshot.rb | 87 +++++++++++++++++++++++++ 3 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 test/scip/testdata/delegate.rb create mode 100644 test/scip/testdata/delegate.snapshot.rb diff --git a/rewriter/Delegate.cc b/rewriter/Delegate.cc index c869a9c80..0b819d875 100644 --- a/rewriter/Delegate.cc +++ b/rewriter/Delegate.cc @@ -95,6 +95,7 @@ vector Delegate::run(core::MutableContext ctx, const ast::Se return empty; } core::NameRef methodName; + core::LocOffsets nameLoc = lit->loc; if (prefixNode) { if (useToAsPrefix && (beforeUnderscore.empty() || beforeUnderscore[0] == '@')) { // Active Support raises at runtime for these cases @@ -118,7 +119,7 @@ vector Delegate::run(core::MutableContext ctx, const ast::Se args.emplace_back(ast::make_expression(loc, ast::MK::Local(loc, core::Names::blkArg()))); methodStubs.push_back( - ast::MK::SyntheticMethod(loc, loc, loc, methodName, std::move(args), ast::MK::EmptyTree())); + ast::MK::SyntheticMethod(loc, loc, nameLoc, methodName, std::move(args), ast::MK::EmptyTree())); } return methodStubs; diff --git a/test/scip/testdata/delegate.rb b/test/scip/testdata/delegate.rb new file mode 100644 index 000000000..b4f8fa9ca --- /dev/null +++ b/test/scip/testdata/delegate.rb @@ -0,0 +1,17 @@ +# typed: true + +class MethodNameManipulation + extend T::Sig + delegate :ball, to: :thing, private: true, allow_nil: true + delegate :foo, :bar, prefix: 'string', to: :thing + delegate :foo, :bar, prefix: :symbol, to: :thing + + sig {void} + def usages + ball(thing: 0) {} + string_foo + string_bar + symbol_foo {} + symbol_bar(1, 2) {} + end +end diff --git a/test/scip/testdata/delegate.snapshot.rb b/test/scip/testdata/delegate.snapshot.rb new file mode 100644 index 000000000..56c2660d6 --- /dev/null +++ b/test/scip/testdata/delegate.snapshot.rb @@ -0,0 +1,87 @@ + # typed: true + + class MethodNameManipulation +# ^^^^^^^^^^^^^^^^^^^^^^ definition [..] MethodNameManipulation# + extend T::Sig +# ^ reference [..] T# +# ^^^ reference [..] T#Sig# + delegate :ball, to: :thing, private: true, allow_nil: true +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Proc# +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#nilable(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# +# ^^^^^ definition [..] MethodNameManipulation#ball(). + delegate :foo, :bar, prefix: 'string', to: :thing +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Proc# +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#nilable(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#nilable(). +# ^^^^ definition [..] MethodNameManipulation#string_foo(). +# ^^^^ definition [..] MethodNameManipulation#string_bar(). + delegate :foo, :bar, prefix: :symbol, to: :thing +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Proc# +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#nilable(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#nilable(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# +# ^^^^ definition [..] MethodNameManipulation#symbol_foo(). +# ^^^^ definition [..] MethodNameManipulation#symbol_bar(). + + sig {void} +# ^^^ reference [..] Sorbet#Private#``#sig(). +# ^^^^^^^^^^ reference [..] Sorbet#Private#Static# +# ^^^^ reference [..] T#Private#Methods#DeclBuilder#void(). + def usages +# ^^^^^^ definition [..] MethodNameManipulation#usages(). + ball(thing: 0) {} +# ^^^^ reference [..] MethodNameManipulation#ball(). + string_foo +# ^^^^^^^^^^ reference [..] MethodNameManipulation#string_foo(). + string_bar +# ^^^^^^^^^^ reference [..] MethodNameManipulation#string_bar(). + symbol_foo {} +# ^^^^^^^^^^ reference [..] MethodNameManipulation#symbol_foo(). + symbol_bar(1, 2) {} +# ^^^^^^^^^^ reference [..] MethodNameManipulation#symbol_bar(). + end + end From 768fd6ee7be51ba5c9f59619de1d2821e1779807 Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Mon, 5 Sep 2022 20:48:45 +0800 Subject: [PATCH 08/19] fix: Fix source locations for Flatfile DSL. --- rewriter/Flatfiles.cc | 19 ++--- test/scip/testdata/flatfile_dsl.rb | 21 +++++ test/scip/testdata/flatfile_dsl.snapshot.rb | 88 +++++++++++++++++++++ 3 files changed, 119 insertions(+), 9 deletions(-) create mode 100644 test/scip/testdata/flatfile_dsl.rb create mode 100644 test/scip/testdata/flatfile_dsl.snapshot.rb diff --git a/rewriter/Flatfiles.cc b/rewriter/Flatfiles.cc index 3354dd3ac..be650273e 100644 --- a/rewriter/Flatfiles.cc +++ b/rewriter/Flatfiles.cc @@ -10,16 +10,16 @@ using namespace std; namespace sorbet::rewriter { -optional getFieldName(core::MutableContext ctx, ast::Send &send) { +optional> getFieldName(core::MutableContext ctx, ast::Send &send) { if (auto propLit = ast::cast_tree(send.getPosArg(0))) { if (propLit->isSymbol()) { - return propLit->asSymbol(); + return make_pair(propLit->asSymbol(), propLit->loc); } } if (send.numPosArgs() >= 2) { if (auto propLit = ast::cast_tree(send.getPosArg(1))) { if (propLit->isSymbol()) { - return propLit->asSymbol(); + return make_pair(propLit->asSymbol(), propLit->loc); } } } @@ -42,20 +42,21 @@ void handleFieldDefinition(core::MutableContext ctx, ast::ExpressionPtr &stat, v !send->recv.isSelfReference() || send->numPosArgs() < 1) { return; } - auto name = getFieldName(ctx, *send); - if (!name) { + auto nameAndLoc = getFieldName(ctx, *send); + if (!nameAndLoc) { return; } + auto [name, nameLoc] = nameAndLoc.value(); methods.emplace_back(ast::MK::Sig0(send->loc, ast::MK::Untyped(send->loc))); - methods.emplace_back( - ast::MK::SyntheticMethod0(send->loc, send->loc, send->loc, *name, ast::MK::Nil(send->loc))); + + methods.emplace_back(ast::MK::SyntheticMethod0(send->loc, send->loc, nameLoc, name, ast::MK::Nil(send->loc))); auto var = ast::MK::Local(send->loc, core::Names::arg0()); - auto setName = name->addEq(ctx); + auto setName = name.addEq(ctx); methods.emplace_back(ast::MK::Sig1(send->loc, ast::MK::Symbol(send->loc, core::Names::arg0()), ast::MK::Untyped(send->loc), ast::MK::Untyped(send->loc))); methods.emplace_back( - ast::MK::SyntheticMethod1(send->loc, send->loc, send->loc, setName, move(var), ast::MK::Nil(send->loc))); + ast::MK::SyntheticMethod1(send->loc, send->loc, nameLoc, setName, move(var), ast::MK::Nil(send->loc))); } } diff --git a/test/scip/testdata/flatfile_dsl.rb b/test/scip/testdata/flatfile_dsl.rb new file mode 100644 index 000000000..a6a1691b4 --- /dev/null +++ b/test/scip/testdata/flatfile_dsl.rb @@ -0,0 +1,21 @@ +# typed: true + +class Record + def self.flatfile; end + def self.from(*_); end + def self.pattern(*_); end + def self.field(*_); end +end + +class Flatfile < Record + flatfile do + from 1..2, :foo + pattern(/A-Za-z/, :bar) + field :baz + end +end + +t = Flatfile.new +t.foo = t.foo + 1 +t.bar = t.bar + 1 +t.baz = t.baz + 1 diff --git a/test/scip/testdata/flatfile_dsl.snapshot.rb b/test/scip/testdata/flatfile_dsl.snapshot.rb new file mode 100644 index 000000000..3ba0716e1 --- /dev/null +++ b/test/scip/testdata/flatfile_dsl.snapshot.rb @@ -0,0 +1,88 @@ + # typed: true + + class Record +# ^^^^^^ definition [..] Record# + def self.flatfile; end +# ^^^^^^^^ definition [..] ``#flatfile(). + def self.from(*_); end +# ^^^^ definition [..] ``#from(). + def self.pattern(*_); end +# ^^^^^^^ definition [..] ``#pattern(). + def self.field(*_); end +# ^^^^^ definition [..] ``#field(). + end + + class Flatfile < Record +# ^^^^^^^^ definition [..] Flatfile# +# ^^^^^^ definition [..] Record# + flatfile do + from 1..2, :foo +# ^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). +# ^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# +# ^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). +# ^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). +# ^^^^^^^^^^^^^^^^^ reference [..] T# +# ^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). +# ^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). +# ^^^^^^^^^^^^^^^^^ reference [..] T# +# ^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# +# ^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). +# ^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). +# ^^^^^^^^^^^^^^^^^ reference [..] T# +# ^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). +# ^^^^ definition [..] Flatfile#`foo=`(). +# ^^^^ definition [..] Flatfile#foo(). + pattern(/A-Za-z/, :bar) +# ^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). +# ^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# +# ^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). +# ^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). +# ^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# +# ^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). +# ^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). +# ^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# +# ^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). +# ^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# +# ^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). +# ^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# +# ^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). +# ^^^^^^^^ reference [..] Regexp# +# ^^^^ definition [..] Flatfile#`bar=`(). +# ^^^^ definition [..] Flatfile#bar(). + field :baz +# ^^^^^^^^^^ reference [..] ``#untyped(). +# ^^^^^^^^^^ reference [..] ``#untyped(). +# ^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). +# ^^^^^^^^^^ reference [..] ``#untyped(). +# ^^^^^^^^^^ reference [..] T# +# ^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). +# ^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). +# ^^^^^^^^^^ reference [..] T# +# ^^^^^^^^^^ reference [..] Sorbet#Private#Static# +# ^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). +# ^^^^^^^^^^ reference [..] Sorbet#Private#Static# +# ^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). +# ^^^^^^^^^^ reference [..] T# +# ^^^^ definition [..] Flatfile#`baz=`(). +# ^^^^ definition [..] Flatfile#baz(). + end + end + + t = Flatfile.new +#^ definition local 1~#119448696 +# ^^^^^^^^ reference [..] Flatfile# + t.foo = t.foo + 1 +#^ reference local 1~#119448696 +# ^^^^^ reference [..] Flatfile#`foo=`(). +# ^ reference local 1~#119448696 +# ^^^ reference [..] Flatfile#foo(). + t.bar = t.bar + 1 +#^ reference local 1~#119448696 +# ^^^^^ reference [..] Flatfile#`bar=`(). +# ^ reference local 1~#119448696 +# ^^^ reference [..] Flatfile#bar(). + t.baz = t.baz + 1 +#^ reference local 1~#119448696 +# ^^^^^ reference [..] Flatfile#`baz=`(). +# ^ reference local 1~#119448696 +# ^^^ reference [..] Flatfile#baz(). From 35b3c8b6e5164c7d093ddc94b53c2a7232306330 Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Tue, 6 Sep 2022 09:00:16 +0800 Subject: [PATCH 09/19] cleanup: Reduce noise in snapshot output. --- scip_indexer/SCIPIndexer.cc | 63 +++++++++++--- test/scip/testdata/def_delegator.snapshot.rb | 86 +------------------ test/scip/testdata/delegate.snapshot.rb | 55 ------------ test/scip/testdata/flatfile_dsl.snapshot.rb | 43 +--------- test/scip/testdata/hoverdocs.snapshot.rb | 28 ------ test/scip/testdata/inheritance.snapshot.rb | 35 -------- .../multifile/basic/def_class1.snapshot.rb | 6 -- test/scip/testdata/struct.snapshot.rb | 29 ------- test/scip/testdata/type_docs.snapshot.rb | 4 - test/scip/testdata/types.snapshot.rb | 5 -- 10 files changed, 56 insertions(+), 298 deletions(-) diff --git a/scip_indexer/SCIPIndexer.cc b/scip_indexer/SCIPIndexer.cc index 9cce9248a..ea8e4a803 100644 --- a/scip_indexer/SCIPIndexer.cc +++ b/scip_indexer/SCIPIndexer.cc @@ -158,6 +158,21 @@ class GemMetadata final { } }; +bool isDescendantOfSorbetPrivateOrT(const core::GlobalState &gs, core::SymbolRef sym) { + UnorderedSet visited; + while (sym.exists() && !visited.contains(sym)) { + if (sym.isClassOrModule()) { + auto klass = sym.asClassOrModuleRef(); + if (klass == core::Symbols::Sorbet_Private() || klass == core::Symbols::T()) { + return true; + } + } + visited.insert(sym); + sym = sym.owner(gs); + } + return false; +} + // A wrapper type to handle both top-level symbols (like classes) as well as // "inner symbols" like fields (@x). In a statically typed language, field // symbols are like any other symbols, but in Ruby, they aren't declared @@ -268,6 +283,18 @@ class NamedSymbolRef final { return this->selfOrOwner; } + bool isSorbetInternalClassOrMethod(const core::GlobalState &gs) const { + switch (this->kind()) { + case Kind::UndeclaredField: + case Kind::DeclaredField: + return false; + case Kind::ClassOrModule: + case Kind::Method: + return isDescendantOfSorbetPrivateOrT(gs, this->asSymbolRef()); + } + ENFORCE(false, "impossible"); + } + vector docStrings(const core::GlobalState &gs, core::TypePtr fieldType, core::Loc loc) { #define CHECK_TYPE(type, name) \ ENFORCE(type, "missing type for {} in file {}\n{}\n", name, loc.file().data(gs).path(), loc.toString(gs)) @@ -673,8 +700,24 @@ class SCIPState { return absl::OkStatus(); } - absl::Status saveReference(const core::GlobalState &gs, core::FileRef file, NamedSymbolRef symRef, - optional overrideType, core::LocOffsets occLoc, int32_t symbol_roles) { + absl::Status saveReference(const core::Context &ctx, NamedSymbolRef symRef, optional overrideType, + core::LocOffsets occLoc, int32_t symbol_roles) { + // HACK: Reduce noise due to in snapshots. + if (ctx.owner.name(ctx) == core::Names::staticInit()) { + if (symRef.kind() == NamedSymbolRef::Kind::Method) { + auto funName = symRef.asSymbolRef().name(ctx); + // NOTE: For the untyped and nilable cases, we would ideally check that + // the owner is :: as well, but this is good enough for now. + if (funName == core::Names::untyped() || funName == core::Names::nilable()) { + return absl::OkStatus(); + } + } + if (symRef.isSorbetInternalClassOrMethod(ctx)) { + return absl::OkStatus(); + } + } + auto &gs = ctx.state; + auto file = ctx.file; // TODO:(varun) Should we cache here to to avoid emitting duplicate references? absl::StatusOr valueOrStatus(this->saveSymbolString(gs, symRef, nullptr)); if (!valueOrStatus.ok()) { @@ -973,7 +1016,7 @@ class CFGTraversal final { status = this->scipState.saveDefinition(gs, file, namedSym, loc); } else { auto overrideType = computeOverrideType(namedSym.definitionType, type); - status = this->scipState.saveReference(gs, file, namedSym, overrideType, loc, referenceRole); + status = this->scipState.saveReference(ctx, namedSym, overrideType, loc, referenceRole); } } else { uint32_t localId = this->functionLocals[localRef]; @@ -1046,7 +1089,7 @@ class CFGTraversal final { status = this->scipState.saveDefinition(gs, file, namedSym, arg.loc); kind = "definition"; } else { - status = this->scipState.saveReference(gs, file, namedSym, nullopt, arg.loc, 0); + status = this->scipState.saveReference(ctx, namedSym, nullopt, arg.loc, 0); kind = "reference"; } ENFORCE(status.ok(), "failed to save {} for {}\ncontext:\ninstruction: {}\nlocation: {}\n", kind, @@ -1115,11 +1158,11 @@ class CFGTraversal final { if (recv.exists()) { auto funSym = gs.lookupMethodSymbol(recv, send->fun); if (funSym.exists()) { - // TODO:(varun) For arrays, hashes etc., try to identify if the function - // matches a known operator (e.g. []=), and emit an appropriate 'WriteAccess' - // symbol role for it. - auto status = this->scipState.saveReference( - gs, file, NamedSymbolRef::method(funSym), nullopt, send->funLoc, 0); + // TODO(varun): For arrays, hashes etc., try to identify if the function + // matches a known operator (e.g. []=), and emit an appropriate + // 'WriteAccess' symbol role for it. + auto status = this->scipState.saveReference(ctx, NamedSymbolRef::method(funSym), + nullopt, send->funLoc, 0); ENFORCE(status.ok()); } } @@ -1226,7 +1269,7 @@ class CFGTraversal final { // Specifically, Go to Definition for modules seems to go to 'module M' even // when other forms like 'class M::C' are present. for (auto &[namedSym, loc] : todo) { - auto status = this->scipState.saveReference(gs, file, namedSym, nullopt, loc, 0); + auto status = this->scipState.saveReference(ctx, namedSym, nullopt, loc, 0); ENFORCE(status.ok(), "status: {}\n", status.message()); } } diff --git a/test/scip/testdata/def_delegator.snapshot.rb b/test/scip/testdata/def_delegator.snapshot.rb index 32c11a421..54f82e9f7 100644 --- a/test/scip/testdata/def_delegator.snapshot.rb +++ b/test/scip/testdata/def_delegator.snapshot.rb @@ -10,16 +10,6 @@ class MyArray1 extend Forwardable # ^^^^^^^^^^^ reference [..] Forwardable# def_delegator :@inner_array, :[], :get_at_index -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#nilable(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Proc# # ^^^^^^^^^^^^^ definition [..] MyArray1#get_at_index(). end @@ -27,24 +17,12 @@ class MyArray1 class MyArray2 # ^^^^^^^^ definition [..] MyArray2# extend T::Sig -# ^ reference [..] T# -# ^^^ reference [..] T#Sig# attr_accessor :inner_array # ^^^^^^^^^^^ definition [..] MyArray2#inner_array(). # ^^^^^^^^^^^ definition [..] MyArray2#`inner_array=`(). extend Forwardable # ^^^^^^^^^^^ reference [..] Forwardable# def_delegator :@inner_array, :[], :get_at_index -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#nilable(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Proc# # ^^^^^^^^^^^^^ definition [..] MyArray2#get_at_index(). end @@ -57,37 +35,7 @@ class MyArray3 extend Forwardable # ^^^^^^^^^^^ reference [..] Forwardable# def_delegators :@inner_array, :size, :<<, :map -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#nilable(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Proc# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#nilable(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#nilable(). # ^^^^^ definition [..] MyArray3#size(). # ^^^ definition [..] MyArray3#`<<`(). # ^^^^ definition [..] MyArray3#map(). @@ -96,45 +44,13 @@ class MyArray3 class MyArray4 # ^^^^^^^^ definition [..] MyArray4# extend T::Sig -# ^ reference [..] T# -# ^^^ reference [..] T#Sig# attr_accessor :inner_array -# ^^^^^^^^^^^ definition [..] MyArray4#`inner_array=`(). # ^^^^^^^^^^^ definition [..] MyArray4#inner_array(). +# ^^^^^^^^^^^ definition [..] MyArray4#`inner_array=`(). extend Forwardable # ^^^^^^^^^^^ reference [..] Forwardable# def_delegators :@inner_array, :size, :<<, :map # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Proc# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#nilable(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#nilable(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#nilable(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). # ^^^^^ definition [..] MyArray4#size(). # ^^^ definition [..] MyArray4#`<<`(). # ^^^^ definition [..] MyArray4#map(). diff --git a/test/scip/testdata/delegate.snapshot.rb b/test/scip/testdata/delegate.snapshot.rb index 56c2660d6..d177aa442 100644 --- a/test/scip/testdata/delegate.snapshot.rb +++ b/test/scip/testdata/delegate.snapshot.rb @@ -3,74 +3,19 @@ class MethodNameManipulation # ^^^^^^^^^^^^^^^^^^^^^^ definition [..] MethodNameManipulation# extend T::Sig -# ^ reference [..] T# -# ^^^ reference [..] T#Sig# delegate :ball, to: :thing, private: true, allow_nil: true -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Proc# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#nilable(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# # ^^^^^ definition [..] MethodNameManipulation#ball(). delegate :foo, :bar, prefix: 'string', to: :thing -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Proc# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#nilable(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#nilable(). # ^^^^ definition [..] MethodNameManipulation#string_foo(). # ^^^^ definition [..] MethodNameManipulation#string_bar(). delegate :foo, :bar, prefix: :symbol, to: :thing # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Proc# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#nilable(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#nilable(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# # ^^^^ definition [..] MethodNameManipulation#symbol_foo(). # ^^^^ definition [..] MethodNameManipulation#symbol_bar(). sig {void} -# ^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^^^^^^^^ reference [..] Sorbet#Private#Static# -# ^^^^ reference [..] T#Private#Methods#DeclBuilder#void(). def usages # ^^^^^^ definition [..] MethodNameManipulation#usages(). ball(thing: 0) {} diff --git a/test/scip/testdata/flatfile_dsl.snapshot.rb b/test/scip/testdata/flatfile_dsl.snapshot.rb index 3ba0716e1..048b2d10f 100644 --- a/test/scip/testdata/flatfile_dsl.snapshot.rb +++ b/test/scip/testdata/flatfile_dsl.snapshot.rb @@ -17,54 +17,15 @@ class Flatfile < Record # ^^^^^^ definition [..] Record# flatfile do from 1..2, :foo -# ^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# -# ^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). -# ^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). -# ^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). -# ^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). -# ^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# -# ^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). -# ^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). -# ^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). # ^^^^ definition [..] Flatfile#`foo=`(). # ^^^^ definition [..] Flatfile#foo(). pattern(/A-Za-z/, :bar) -# ^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). -# ^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# -# ^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). -# ^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). -# ^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). -# ^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). -# ^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# -# ^^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). -# ^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). # ^^^^^^^^ reference [..] Regexp# -# ^^^^ definition [..] Flatfile#`bar=`(). # ^^^^ definition [..] Flatfile#bar(). +# ^^^^ definition [..] Flatfile#`bar=`(). field :baz -# ^^^^^^^^^^ reference [..] ``#untyped(). -# ^^^^^^^^^^ reference [..] ``#untyped(). -# ^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). -# ^^^^^^^^^^ reference [..] ``#untyped(). -# ^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). -# ^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^^^^^^^^ reference [..] T# -# ^^^^^^^^^^ reference [..] Sorbet#Private#Static# -# ^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). -# ^^^^^^^^^^ reference [..] Sorbet#Private#Static# -# ^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^^^^^^^^ reference [..] T# -# ^^^^ definition [..] Flatfile#`baz=`(). # ^^^^ definition [..] Flatfile#baz(). +# ^^^^ definition [..] Flatfile#`baz=`(). end end diff --git a/test/scip/testdata/hoverdocs.snapshot.rb b/test/scip/testdata/hoverdocs.snapshot.rb index 58a636859..3f37950e4 100644 --- a/test/scip/testdata/hoverdocs.snapshot.rb +++ b/test/scip/testdata/hoverdocs.snapshot.rb @@ -11,8 +11,6 @@ class C1 # documentation # | Class doc comment extend T::Sig -# ^ reference [..] T# -# ^^^ reference [..] T#Sig# def m1 # ^^ definition [..] C1#m1(). @@ -24,11 +22,7 @@ def m1 end sig { returns(T::Boolean) } -# ^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). -# ^ reference [..] T# # ^^^^^^^ reference [..] T#Boolean. -# ^^^^^^^^^^ reference [..] Sorbet#Private#Static# def m2 # ^^ definition [..] C1#m2(). # documentation @@ -40,15 +34,9 @@ def m2 end sig { params(C, T::Boolean).returns(T::Boolean) } -# ^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). # ^ reference [..] `T.untyped`# -# ^ reference [..] T# # ^^^^^^^ reference [..] T#Boolean. -# ^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). -# ^ reference [..] T# # ^^^^^^^ reference [..] T#Boolean. -# ^^^^^^^^^^ reference [..] Sorbet#Private#Static# def m3(c, b) # ^^ definition [..] C1#m3(). # documentation @@ -95,11 +83,7 @@ def m4(xs) # Yet another.. # ...doc comment sig { returns(T::Boolean) } -# ^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). -# ^ reference [..] T# # ^^^^^^^ reference [..] T#Boolean. -# ^^^^^^^^^^ reference [..] Sorbet#Private#Static# def m5 # ^^ definition [..] C1#m5(). # documentation @@ -116,15 +100,9 @@ def m5 # And... # ...one more doc comment sig { params(C, T::Boolean).returns(T::Boolean) } -# ^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). # ^ reference [..] `T.untyped`# -# ^ reference [..] T# # ^^^^^^^ reference [..] T#Boolean. -# ^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). -# ^ reference [..] T# # ^^^^^^^ reference [..] T#Boolean. -# ^^^^^^^^^^ reference [..] Sorbet#Private#Static# def m6(c, b) # ^^ definition [..] C1#m6(). # documentation @@ -193,16 +171,10 @@ module M2 # documentation # | This module is nested inside M1 extend T::Sig -# ^ reference [..] T# -# ^^^ reference [..] T#Sig# # This method is inside M1::M2 sig { returns(T::Boolean) } -# ^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). -# ^ reference [..] T# # ^^^^^^^ reference [..] T#Boolean. -# ^^^^^^^^^^ reference [..] Sorbet#Private#Static# def n1 # ^^ definition [..] M1#M2#n1(). # documentation diff --git a/test/scip/testdata/inheritance.snapshot.rb b/test/scip/testdata/inheritance.snapshot.rb index 13399dc3e..8556c248a 100644 --- a/test/scip/testdata/inheritance.snapshot.rb +++ b/test/scip/testdata/inheritance.snapshot.rb @@ -3,16 +3,9 @@ class Z1 # ^^ definition [..] Z1# extend T::Sig -# ^ reference [..] T# -# ^^^ reference [..] T#Sig# sig { params(a: T::Boolean).void } -# ^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). -# ^ reference [..] T# # ^^^^^^^ reference [..] T#Boolean. -# ^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# -# ^^^^ reference [..] T#Private#Methods#DeclBuilder#void(). def write_f(a) # ^^^^^^^ definition [..] Z1#write_f(). # ^ definition local 1~#1000661517 @@ -23,11 +16,7 @@ def write_f(a) end sig { returns(T::Boolean) } -# ^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). -# ^ reference [..] T# # ^^^^^^^ reference [..] T#Boolean. -# ^^^^^^^^^^ reference [..] Sorbet#Private#Static# def read_f? # ^^^^^^^ definition [..] Z1#`read_f?`(). @f @@ -38,15 +27,9 @@ def read_f? class Z2 # ^^ definition [..] Z2# extend T::Sig -# ^ reference [..] T# -# ^^^ reference [..] T#Sig# sig { returns(T::Boolean) } -# ^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). -# ^ reference [..] T# # ^^^^^^^ reference [..] T#Boolean. -# ^^^^^^^^^^ reference [..] Sorbet#Private#Static# def read_f? # ^^^^^^^ definition [..] Z2#`read_f?`(). @f @@ -54,12 +37,7 @@ def read_f? end sig { params(a: T::Boolean).void } -# ^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). -# ^ reference [..] T# # ^^^^^^^ reference [..] T#Boolean. -# ^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# -# ^^^^ reference [..] T#Private#Methods#DeclBuilder#void(). def write_f(a) # ^^^^^^^ definition [..] Z2#write_f(). # ^ definition local 1~#1000661517 @@ -74,15 +52,9 @@ class Z3 < Z1 # ^^ definition [..] Z3# # ^^ definition [..] Z1# extend T::Sig -# ^ reference [..] T# -# ^^^ reference [..] T#Sig# sig { returns(T::Boolean) } -# ^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). -# ^ reference [..] T# # ^^^^^^^ reference [..] T#Boolean. -# ^^^^^^^^^^ reference [..] Sorbet#Private#Static# def read_f_plus_1? # ^^^^^^^^^^^^^^ definition [..] Z3#`read_f_plus_1?`(). @f + 1 @@ -94,16 +66,9 @@ class Z4 < Z3 # ^^ definition [..] Z4# # ^^ definition [..] Z3# extend T::Sig -# ^ reference [..] T# -# ^^^ reference [..] T#Sig# sig { params(a: T::Boolean).void } -# ^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). -# ^ reference [..] T# # ^^^^^^^ reference [..] T#Boolean. -# ^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# -# ^^^^ reference [..] T#Private#Methods#DeclBuilder#void(). def write_f_plus_1(a) # ^^^^^^^^^^^^^^ definition [..] Z4#write_f_plus_1(). # ^ definition local 1~#3337417690 diff --git a/test/scip/testdata/multifile/basic/def_class1.snapshot.rb b/test/scip/testdata/multifile/basic/def_class1.snapshot.rb index 3ac78ff8e..3435f1bcf 100644 --- a/test/scip/testdata/multifile/basic/def_class1.snapshot.rb +++ b/test/scip/testdata/multifile/basic/def_class1.snapshot.rb @@ -3,15 +3,9 @@ class C1 # ^^ definition [..] C1# extend T::Sig -# ^ reference [..] T# -# ^^^ reference [..] T#Sig# sig { returns(T::Boolean) } -# ^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). -# ^ reference [..] T# # ^^^^^^^ reference [..] T#Boolean. -# ^^^^^^^^^^ reference [..] Sorbet#Private#Static# def m1 # ^^ definition [..] C1#m1(). true diff --git a/test/scip/testdata/struct.snapshot.rb b/test/scip/testdata/struct.snapshot.rb index b4da21e14..2ac13f43d 100644 --- a/test/scip/testdata/struct.snapshot.rb +++ b/test/scip/testdata/struct.snapshot.rb @@ -4,20 +4,9 @@ class S < T::Struct # ^ definition [..] S# # ^ reference [..] T# -# ^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). -# ^^^^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^^^^ reference [..] Sorbet#Private#Static# # ^^^^^^ definition [..] S#initialize(). # ^^^^^^ definition [..] T#Struct# -# ^^^^^^ reference [..] T#Private#Methods#DeclBuilder#void(). prop :prop_i, Integer -# ^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# -# ^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). -# ^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). -# ^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). -# ^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# # ^^^^^^ definition [..] S#`prop_i=`(). # ^^^^^^ definition [..] S#prop_i(). # ^^^^^^^ reference [..] Integer# @@ -26,23 +15,11 @@ class S < T::Struct # ^^^^^^^ reference [..] Integer# # ^^^^^^^ reference [..] Integer# const :const_s, T.nilable(String) -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# # ^^^^^^^ definition [..] S#const_s(). -# ^ reference [..] T# -# ^ reference [..] T# -# ^ reference [..] T# -# ^^^^^^^ reference [..] ``#nilable(). -# ^^^^^^^ reference [..] ``#nilable(). -# ^^^^^^^ reference [..] ``#nilable(). # ^^^^^^ reference [..] String# # ^^^^^^ reference [..] String# # ^^^^^^ reference [..] String# const :const_f, Float, default: 0.5 -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#returns(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# # ^^^^^^^ definition [..] S#const_f(). # ^^^^^ reference [..] Float# # ^^^^^ reference [..] Float# @@ -78,12 +55,6 @@ def f #^^^^^ definition [..] POINT# #^^^^^^^^^^^^^^^^^^^^ definition [..] Struct# #^^^^^^^^^^^^^^^^^^^^ definition [..] POINT#initialize(). -#^^^^^^^^^^^^^^^^^^^^ reference [..] ``#untyped(). -#^^^^^^^^^^^^^^^^^^^^ reference [..] T# -#^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#void(). -#^^^^^^^^^^^^^^^^^^^^ reference [..] T#Private#Methods#DeclBuilder#params(). -#^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#``#sig(). -#^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# #^^^^^^^^^^^^^^^^^^^^ definition local 5~#119448696 # ^ definition [..] POINT#x(). # ^ definition [..] POINT#`x=`(). diff --git a/test/scip/testdata/type_docs.snapshot.rb b/test/scip/testdata/type_docs.snapshot.rb index d239c7502..3d8823572 100644 --- a/test/scip/testdata/type_docs.snapshot.rb +++ b/test/scip/testdata/type_docs.snapshot.rb @@ -8,12 +8,8 @@ module M # | module M # | ``` extent T::Sig -# ^ reference [..] T# -# ^^^ reference [..] T#Sig# sig { params(x: Integer, y: String).returns(String) } -# ^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Sorbet#Private#Static# # ^^^^^^^ reference [..] Integer# # ^^^^^^ reference [..] String# # ^^^^^^ reference [..] String# diff --git a/test/scip/testdata/types.snapshot.rb b/test/scip/testdata/types.snapshot.rb index 276c580ae..43a562e89 100644 --- a/test/scip/testdata/types.snapshot.rb +++ b/test/scip/testdata/types.snapshot.rb @@ -11,13 +11,8 @@ module M # ^ definition [..] M# module_function sig { returns(T::Boolean) } -# ^^^ reference [..] Sorbet#Private#``#sig(). -# ^^^ reference [..] Sorbet#Private#``#sig(). -# ^ reference [..] T# # ^^^^^^^ reference [..] T#Boolean. # ^^^^^^^ reference [..] T#Boolean. -# ^^^^^^^^^^ reference [..] Sorbet#Private#Static# -# ^^^^^^^^^^ reference [..] Sorbet#Private#Static# def b # ^ definition [..] M#b(). # ^ definition [..] ``#b(). From f379c50bf5b13915204aed2b4aeb47a3e830e5d9 Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Tue, 6 Sep 2022 10:31:24 +0800 Subject: [PATCH 10/19] test: Add test cases for cattr, mattr, minitest. --- scip_indexer/SCIPIndexer.cc | 15 +-- test/scip/testdata/cattr.rb | 61 ++++++++++++ test/scip/testdata/cattr.snapshot.rb | 120 +++++++++++++++++++++++ test/scip/testdata/mattr.rb | 63 ++++++++++++ test/scip/testdata/mattr.snapshot.rb | 122 ++++++++++++++++++++++++ test/scip/testdata/minitest.rb | 78 +++++++++++++++ test/scip/testdata/minitest.snapshot.rb | 112 ++++++++++++++++++++++ 7 files changed, 560 insertions(+), 11 deletions(-) create mode 100644 test/scip/testdata/cattr.rb create mode 100644 test/scip/testdata/cattr.snapshot.rb create mode 100644 test/scip/testdata/mattr.rb create mode 100644 test/scip/testdata/mattr.snapshot.rb create mode 100644 test/scip/testdata/minitest.rb create mode 100644 test/scip/testdata/minitest.snapshot.rb diff --git a/scip_indexer/SCIPIndexer.cc b/scip_indexer/SCIPIndexer.cc index ea8e4a803..31cfd41a9 100644 --- a/scip_indexer/SCIPIndexer.cc +++ b/scip_indexer/SCIPIndexer.cc @@ -158,12 +158,13 @@ class GemMetadata final { } }; -bool isDescendantOfSorbetPrivateOrT(const core::GlobalState &gs, core::SymbolRef sym) { +bool isSorbetInternal(const core::GlobalState &gs, core::SymbolRef sym) { UnorderedSet visited; + auto classT = core::Symbols::T().data(gs)->lookupSingletonClass(gs); while (sym.exists() && !visited.contains(sym)) { if (sym.isClassOrModule()) { auto klass = sym.asClassOrModuleRef(); - if (klass == core::Symbols::Sorbet_Private() || klass == core::Symbols::T()) { + if (klass == core::Symbols::Sorbet_Private() || klass == core::Symbols::T() || klass == classT) { return true; } } @@ -290,7 +291,7 @@ class NamedSymbolRef final { return false; case Kind::ClassOrModule: case Kind::Method: - return isDescendantOfSorbetPrivateOrT(gs, this->asSymbolRef()); + return isSorbetInternal(gs, this->asSymbolRef()); } ENFORCE(false, "impossible"); } @@ -704,14 +705,6 @@ class SCIPState { core::LocOffsets occLoc, int32_t symbol_roles) { // HACK: Reduce noise due to in snapshots. if (ctx.owner.name(ctx) == core::Names::staticInit()) { - if (symRef.kind() == NamedSymbolRef::Kind::Method) { - auto funName = symRef.asSymbolRef().name(ctx); - // NOTE: For the untyped and nilable cases, we would ideally check that - // the owner is :: as well, but this is good enough for now. - if (funName == core::Names::untyped() || funName == core::Names::nilable()) { - return absl::OkStatus(); - } - } if (symRef.isSorbetInternalClassOrMethod(ctx)) { return absl::OkStatus(); } diff --git a/test/scip/testdata/cattr.rb b/test/scip/testdata/cattr.rb new file mode 100644 index 000000000..72d40a119 --- /dev/null +++ b/test/scip/testdata/cattr.rb @@ -0,0 +1,61 @@ +# typed: strict + +class CR + extend T::Sig + cattr_reader :both, :foo + cattr_reader :no_instance, instance_accessor: false + cattr_reader :bar, :no_reader, instance_reader: false + + sig {void} + def usages + both + end + + both + no_instance + no_reader +end + +class CW + extend T::Sig + cattr_writer :both, :foo + cattr_writer :no_instance, instance_accessor: false + cattr_writer :bar, :no_instance_writer, instance_writer: false + + sig {void} + def usages + self.both = 1 + end + + self.both = 1 + self.no_instance = 1 + self.no_instance_writer = 1 +end + +class CA + extend T::Sig + cattr_accessor :both, :foo + cattr_accessor :no_instance, instance_accessor: false + cattr_accessor :no_instance_reader, instance_reader: false + cattr_accessor :bar, :no_instance_writer, instance_writer: false + + sig {void} + def usages + both + self.both = 1 + self.no_instance_reader= 1 + no_instance_writer + end + + both + self.both = 1 + + no_instance + self.no_instance = 1 + + no_instance_reader + self.no_instance_reader = 1 + + no_instance_writer + self.no_instance_writer = 1 +end diff --git a/test/scip/testdata/cattr.snapshot.rb b/test/scip/testdata/cattr.snapshot.rb new file mode 100644 index 000000000..af63aaf7f --- /dev/null +++ b/test/scip/testdata/cattr.snapshot.rb @@ -0,0 +1,120 @@ + # typed: strict + + class CR +# ^^ definition [..] CR# + extend T::Sig + cattr_reader :both, :foo +# ^^^^^ definition [..] CR#both(). +# ^^^^^ definition [..] ``#both(). +# ^^^^ definition [..] CR#foo(). +# ^^^^ definition [..] ``#foo(). + cattr_reader :no_instance, instance_accessor: false +# ^^^^^^^^^^^^ definition [..] ``#no_instance(). + cattr_reader :bar, :no_reader, instance_reader: false +# ^^^^ definition [..] ``#bar(). +# ^^^^^^^^^^ definition [..] ``#no_reader(). + + sig {void} + def usages +# ^^^^^^ definition [..] CR#usages(). + both +# ^^^^ reference [..] CR#both(). + end + + both +# ^^^^ reference [..] ``#both(). + no_instance +# ^^^^^^^^^^^ reference [..] ``#no_instance(). + no_reader +# ^^^^^^^^^ reference [..] ``#no_reader(). + end + + class CW +# ^^ definition [..] CW# + extend T::Sig + cattr_writer :both, :foo +# ^^^^^ definition [..] CW#`both=`(). +# ^^^^^ definition [..] ``#`both=`(). +# ^^^^ definition [..] CW#`foo=`(). +# ^^^^ definition [..] ``#`foo=`(). + cattr_writer :no_instance, instance_accessor: false +# ^^^^^^^^^^^^ definition [..] ``#`no_instance=`(). + cattr_writer :bar, :no_instance_writer, instance_writer: false +# ^^^^ definition [..] ``#`bar=`(). +# ^^^^^^^^^^^^^^^^^^^ definition [..] ``#`no_instance_writer=`(). + + sig {void} + def usages +# ^^^^^^ definition [..] CW#usages(). + self.both = 1 +# ^^^^^^ reference [..] CW#`both=`(). + end + + self.both = 1 +# ^^^^^^ reference [..] ``#`both=`(). + self.no_instance = 1 +# ^^^^^^^^^^^^^ reference [..] ``#`no_instance=`(). + self.no_instance_writer = 1 +# ^^^^^^^^^^^^^^^^^^^^ reference [..] ``#`no_instance_writer=`(). + end + + class CA +# ^^ definition [..] CA# + extend T::Sig + cattr_accessor :both, :foo +# ^^^^^ definition [..] CA#`both=`(). +# ^^^^^ definition [..] ``#both(). +# ^^^^^ definition [..] CA#both(). +# ^^^^^ definition [..] ``#`both=`(). +# ^^^^ definition [..] CA#foo(). +# ^^^^ definition [..] ``#foo(). +# ^^^^ definition [..] CA#`foo=`(). +# ^^^^ definition [..] ``#`foo=`(). + cattr_accessor :no_instance, instance_accessor: false +# ^^^^^^^^^^^^ definition [..] ``#no_instance(). +# ^^^^^^^^^^^^ definition [..] ``#`no_instance=`(). + cattr_accessor :no_instance_reader, instance_reader: false +# ^^^^^^^^^^^^^^^^^^^ definition [..] ``#no_instance_reader(). +# ^^^^^^^^^^^^^^^^^^^ definition [..] CA#`no_instance_reader=`(). +# ^^^^^^^^^^^^^^^^^^^ definition [..] ``#`no_instance_reader=`(). + cattr_accessor :bar, :no_instance_writer, instance_writer: false +# ^^^^ definition [..] CA#bar(). +# ^^^^ definition [..] ``#bar(). +# ^^^^ definition [..] ``#`bar=`(). +# ^^^^^^^^^^^^^^^^^^^ definition [..] CA#no_instance_writer(). +# ^^^^^^^^^^^^^^^^^^^ definition [..] ``#no_instance_writer(). +# ^^^^^^^^^^^^^^^^^^^ definition [..] ``#`no_instance_writer=`(). + + sig {void} + def usages +# ^^^^^^ definition [..] CA#usages(). + both +# ^^^^ reference [..] CA#both(). + self.both = 1 +# ^^^^^^ reference [..] CA#`both=`(). + self.no_instance_reader= 1 +# ^^^^^^^^^^^^^^^^^^^ reference [..] CA#`no_instance_reader=`(). + no_instance_writer +# ^^^^^^^^^^^^^^^^^^ reference [..] CA#no_instance_writer(). + end + + both +# ^^^^ reference [..] ``#both(). + self.both = 1 +# ^^^^^^ reference [..] ``#`both=`(). + + no_instance +# ^^^^^^^^^^^ reference [..] ``#no_instance(). + self.no_instance = 1 +# ^^^^^^^^^^^^^ reference [..] ``#`no_instance=`(). + + no_instance_reader +# ^^^^^^^^^^^^^^^^^^ reference [..] ``#no_instance_reader(). + self.no_instance_reader = 1 +# ^^^^^^^^^^^^^^^^^^^^ reference [..] ``#`no_instance_reader=`(). + + no_instance_writer +# ^^^^^^^^^^^^^^^^^^ reference [..] ``#no_instance_writer(). + self.no_instance_writer = 1 +# ^^^^^^^^^^^^^^^^^^^^ reference [..] ``#`no_instance_writer=`(). + end diff --git a/test/scip/testdata/mattr.rb b/test/scip/testdata/mattr.rb new file mode 100644 index 000000000..c6e4001a0 --- /dev/null +++ b/test/scip/testdata/mattr.rb @@ -0,0 +1,63 @@ +# typed: strict + +class MR + extend T::Sig + mattr_reader :both, :foo + mattr_reader :no_instance, instance_accessor: false + mattr_reader :bar, :no_instance_reader, instance_reader: false + + sig {void} + def usages + both + end + + both + no_instance + no_instance_reader +end + +class MW + extend T::Sig + mattr_writer :both, :foo + mattr_writer :no_instance, instance_accessor: false + mattr_writer :bar, :no_instance_writer, instance_writer: false + + sig {void} + def usages + self.both = 1 + end + + self.both = 1 + self.no_instance = 1 + self.no_instance_writer = 1 +end + +class MA + extend T::Sig + mattr_accessor :both, :foo + mattr_accessor :no_instance, instance_accessor: false + mattr_accessor :no_instance_reader, instance_reader: false + mattr_accessor :bar, :no_instance_writer, instance_writer: false + + sig {void} + def usages + both + self.both = 1 + + self.no_instance_reader= 1 + + no_instance_writer + end + + both + self.both = 1 + + no_instance + self.no_instance = 1 + + no_instance_reader + self.no_instance_reader = 1 + + no_instance_writer + self.no_instance_writer = 1 +end diff --git a/test/scip/testdata/mattr.snapshot.rb b/test/scip/testdata/mattr.snapshot.rb new file mode 100644 index 000000000..abbc161f7 --- /dev/null +++ b/test/scip/testdata/mattr.snapshot.rb @@ -0,0 +1,122 @@ + # typed: strict + + class MR +# ^^ definition [..] MR# + extend T::Sig + mattr_reader :both, :foo +# ^^^^^ definition [..] MR#both(). +# ^^^^^ definition [..] ``#both(). +# ^^^^ definition [..] MR#foo(). +# ^^^^ definition [..] ``#foo(). + mattr_reader :no_instance, instance_accessor: false +# ^^^^^^^^^^^^ definition [..] ``#no_instance(). + mattr_reader :bar, :no_instance_reader, instance_reader: false +# ^^^^ definition [..] ``#bar(). +# ^^^^^^^^^^^^^^^^^^^ definition [..] ``#no_instance_reader(). + + sig {void} + def usages +# ^^^^^^ definition [..] MR#usages(). + both +# ^^^^ reference [..] MR#both(). + end + + both +# ^^^^ reference [..] ``#both(). + no_instance +# ^^^^^^^^^^^ reference [..] ``#no_instance(). + no_instance_reader +# ^^^^^^^^^^^^^^^^^^ reference [..] ``#no_instance_reader(). + end + + class MW +# ^^ definition [..] MW# + extend T::Sig + mattr_writer :both, :foo +# ^^^^^ definition [..] MW#`both=`(). +# ^^^^^ definition [..] ``#`both=`(). +# ^^^^ definition [..] MW#`foo=`(). +# ^^^^ definition [..] ``#`foo=`(). + mattr_writer :no_instance, instance_accessor: false +# ^^^^^^^^^^^^ definition [..] ``#`no_instance=`(). + mattr_writer :bar, :no_instance_writer, instance_writer: false +# ^^^^ definition [..] ``#`bar=`(). +# ^^^^^^^^^^^^^^^^^^^ definition [..] ``#`no_instance_writer=`(). + + sig {void} + def usages +# ^^^^^^ definition [..] MW#usages(). + self.both = 1 +# ^^^^^^ reference [..] MW#`both=`(). + end + + self.both = 1 +# ^^^^^^ reference [..] ``#`both=`(). + self.no_instance = 1 +# ^^^^^^^^^^^^^ reference [..] ``#`no_instance=`(). + self.no_instance_writer = 1 +# ^^^^^^^^^^^^^^^^^^^^ reference [..] ``#`no_instance_writer=`(). + end + + class MA +# ^^ definition [..] MA# + extend T::Sig + mattr_accessor :both, :foo +# ^^^^^ definition [..] MA#`both=`(). +# ^^^^^ definition [..] ``#both(). +# ^^^^^ definition [..] MA#both(). +# ^^^^^ definition [..] ``#`both=`(). +# ^^^^ definition [..] MA#foo(). +# ^^^^ definition [..] ``#foo(). +# ^^^^ definition [..] MA#`foo=`(). +# ^^^^ definition [..] ``#`foo=`(). + mattr_accessor :no_instance, instance_accessor: false +# ^^^^^^^^^^^^ definition [..] ``#no_instance(). +# ^^^^^^^^^^^^ definition [..] ``#`no_instance=`(). + mattr_accessor :no_instance_reader, instance_reader: false +# ^^^^^^^^^^^^^^^^^^^ definition [..] ``#no_instance_reader(). +# ^^^^^^^^^^^^^^^^^^^ definition [..] MA#`no_instance_reader=`(). +# ^^^^^^^^^^^^^^^^^^^ definition [..] ``#`no_instance_reader=`(). + mattr_accessor :bar, :no_instance_writer, instance_writer: false +# ^^^^ definition [..] MA#bar(). +# ^^^^ definition [..] ``#bar(). +# ^^^^ definition [..] ``#`bar=`(). +# ^^^^^^^^^^^^^^^^^^^ definition [..] MA#no_instance_writer(). +# ^^^^^^^^^^^^^^^^^^^ definition [..] ``#no_instance_writer(). +# ^^^^^^^^^^^^^^^^^^^ definition [..] ``#`no_instance_writer=`(). + + sig {void} + def usages +# ^^^^^^ definition [..] MA#usages(). + both +# ^^^^ reference [..] MA#both(). + self.both = 1 +# ^^^^^^ reference [..] MA#`both=`(). + + self.no_instance_reader= 1 +# ^^^^^^^^^^^^^^^^^^^ reference [..] MA#`no_instance_reader=`(). + + no_instance_writer +# ^^^^^^^^^^^^^^^^^^ reference [..] MA#no_instance_writer(). + end + + both +# ^^^^ reference [..] ``#both(). + self.both = 1 +# ^^^^^^ reference [..] ``#`both=`(). + + no_instance +# ^^^^^^^^^^^ reference [..] ``#no_instance(). + self.no_instance = 1 +# ^^^^^^^^^^^^^ reference [..] ``#`no_instance=`(). + + no_instance_reader +# ^^^^^^^^^^^^^^^^^^ reference [..] ``#no_instance_reader(). + self.no_instance_reader = 1 +# ^^^^^^^^^^^^^^^^^^^^ reference [..] ``#`no_instance_reader=`(). + + no_instance_writer +# ^^^^^^^^^^^^^^^^^^ reference [..] ``#no_instance_writer(). + self.no_instance_writer = 1 +# ^^^^^^^^^^^^^^^^^^^^ reference [..] ``#`no_instance_writer=`(). + end diff --git a/test/scip/testdata/minitest.rb b/test/scip/testdata/minitest.rb new file mode 100644 index 000000000..4ec4734d4 --- /dev/null +++ b/test/scip/testdata/minitest.rb @@ -0,0 +1,78 @@ +# typed: true +class MyTest + def outside_method + end + + it "works outside" do + outside_method + end + + it "allows constants inside of IT" do + CONST = 10 + end + + it "allows let-ed constants inside of IT" do + C2 = T.let(10, Integer) + end + + it "allows path constants inside of IT" do + C3 = Mod::C + C3.new + end + + describe "some inner tests" do + def inside_method + end + + it "works inside" do + outside_method + inside_method + end + end + + def instance_helper; end + + before do + @foo = T.let(3, Integer) + instance_helper + end + + it 'can read foo' do + T.assert_type!(@foo, Integer) + instance_helper + end + + def self.random_method + end + + describe Object do + it Object do + end + it Object do + end + end + + def self.it(*args) + end + it "ignores methods without a block" + + junk.it "ignores non-self calls" do + junk + end + + describe "a non-ideal situation" do + it "contains nested describes" do + describe "nobody should write this but we should still parse it" do + end + end + end +end + +def junk +end + + +module Mod + class C + end +end diff --git a/test/scip/testdata/minitest.snapshot.rb b/test/scip/testdata/minitest.snapshot.rb new file mode 100644 index 000000000..51762b6a3 --- /dev/null +++ b/test/scip/testdata/minitest.snapshot.rb @@ -0,0 +1,112 @@ + # typed: true + class MyTest +# ^^^^^^ definition [..] MyTest# + def outside_method +# ^^^^^^^^^^^^^^ definition [..] MyTest#outside_method(). + end + + it "works outside" do +# ^^^ definition [..] MyTest#``(). + outside_method + end + + it "allows constants inside of IT" do +# ^^^^^^^ definition [..] MyTest#``(). + CONST = 10 +# ^^^^^ definition [..] MyTest#CONST. +# ^^^^^^^^^^ reference [..] Kernel# + end + + it "allows let-ed constants inside of IT" do +# ^^^^^^^^^^^ definition [..] MyTest#``(). + C2 = T.let(10, Integer) +# ^^ definition [..] MyTest#C2. +# ^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Kernel# +# ^^^^^^^ reference [..] Integer# + end + + it "allows path constants inside of IT" do + C3 = Mod::C +# ^^ definition [..] MyTest#C3. +# ^^^ reference [..] Mod# +# ^ reference [..] Mod#C# +# ^^^^ definition [..] MyTest#``(). + C3.new + end + + describe "some inner tests" do +# ^^^^^^^^^^^^^^^^^^ definition [..] MyTest#``# + def inside_method +# ^^^^^^^^^^^^^ definition [..] MyTest#``#inside_method(). + end + + it "works inside" do +# ^^^^^^^^^^^^^^^^^^^^^ definition [..] MyTest#``#``(). + outside_method + inside_method + end + end + + def instance_helper; end +# ^^^^^^^^^^^^^^^ definition [..] MyTest#instance_helper(). + + before do +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] MyTest#initialize(). + @foo = T.let(3, Integer) + instance_helper + end + + it 'can read foo' do +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] MyTest#``(). + T.assert_type!(@foo, Integer) + instance_helper + end + + def self.random_method +# ^^^^^^^^^^^^^ definition [..] ``#random_method(). + end + + describe Object do +# ^^^^^^ definition [..] MyTest#``# + it Object do +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] MyTest#``#``(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] MyTest#``#``(). +# ^^^^^^ reference [..] Object# + end + it Object do +# ^^^^^^ reference [..] Object# + end + end + + def self.it(*args) +# ^^ definition [..] ``#it(). + end + it "ignores methods without a block" +# ^^ reference [..] ``#it(). + + junk.it "ignores non-self calls" do + junk + end + + describe "a non-ideal situation" do +# ^^^^^^^^^^^^^^^^^^^^^^^ definition [..] MyTest#``# + it "contains nested describes" do +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] MyTest#``#``(). + describe "nobody should write this but we should still parse it" do +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] MyTest#``#``# + end + end + end + end + + def junk +# ^^^^ definition [..] Object#junk(). + end + + + module Mod +# ^^^ definition [..] Mod# + class C +# ^ definition [..] Mod#C# + end + end From aafb4932deea1c8782148ea04476f1a374d0b46f Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Tue, 6 Sep 2022 12:38:34 +0800 Subject: [PATCH 11/19] test: Add test for singleton + remove TODOs. --- rewriter/Singleton.cc | 1 - rewriter/Struct.cc | 1 - test/scip/testdata/singleton.rb | 18 +++++++++++++ test/scip/testdata/singleton.snapshot.rb | 32 ++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 test/scip/testdata/singleton.rb create mode 100644 test/scip/testdata/singleton.snapshot.rb diff --git a/rewriter/Singleton.cc b/rewriter/Singleton.cc index 9bb6dccea..c3a526e6f 100644 --- a/rewriter/Singleton.cc +++ b/rewriter/Singleton.cc @@ -84,7 +84,6 @@ void Singleton::run(core::MutableContext ctx, ast::ClassDef *cdef) { } { - // TODO(varun): Not sure if 'loc' is the right 'nameLoc' here. auto method = ast::MK::SyntheticMethod0(loc, loc, loc, core::Names::instance(), ast::MK::RaiseUnimplemented(loc)); ast::cast_tree_nonnull(method).flags.isSelfMethod = true; diff --git a/rewriter/Struct.cc b/rewriter/Struct.cc index 4fc83be1e..988e9cd62 100644 --- a/rewriter/Struct.cc +++ b/rewriter/Struct.cc @@ -138,7 +138,6 @@ vector Struct::run(core::MutableContext ctx, ast::Assign *as argName = ast::make_expression(symLoc, move(argName)); } newArgs.emplace_back(ast::MK::OptionalArg(symLoc, move(argName), ast::MK::Nil(symLoc))); - // TODO(varun): Is symLoc correct here? body.emplace_back(ast::MK::SyntheticMethod0(symLoc, symLoc, symLoc, name, ast::MK::RaiseUnimplemented(loc))); body.emplace_back(ast::MK::SyntheticMethod1(symLoc, symLoc, symLoc, name.addEq(ctx), ast::MK::Local(symLoc, name), ast::MK::RaiseUnimplemented(loc))); diff --git a/test/scip/testdata/singleton.rb b/test/scip/testdata/singleton.rb new file mode 100644 index 000000000..46c01b5c2 --- /dev/null +++ b/test/scip/testdata/singleton.rb @@ -0,0 +1,18 @@ +# typed: true + +class A + include Singleton +end + +# Singleton supports inheritance, turning the sub-class into a singleton as well. +class B < A; end + +class C + include Singleton + extend T::Helpers + final! +end + +def f + return [A.instance, B.instance, C.instance] +end diff --git a/test/scip/testdata/singleton.snapshot.rb b/test/scip/testdata/singleton.snapshot.rb new file mode 100644 index 000000000..82901b445 --- /dev/null +++ b/test/scip/testdata/singleton.snapshot.rb @@ -0,0 +1,32 @@ + # typed: true + + class A +# ^ definition [..] A# + include Singleton +# ^^^^^^^^^^^^^^^^^ definition [..] ``#instance(). +# ^^^^^^^^^ reference [..] Singleton# + end + + # Singleton supports inheritance, turning the sub-class into a singleton as well. + class B < A; end +# ^ definition [..] B# +# ^ definition [..] A# + + class C +# ^ definition [..] C# + include Singleton +# ^^^^^^^^^^^^^^^^^ definition [..] ``#instance(). +# ^^^^^^^^^ reference [..] Singleton# + extend T::Helpers + final! + end + + def f +# ^ definition [..] Object#f(). + return [A.instance, B.instance, C.instance] +# ^ reference [..] A# +# ^^^^^^^^ reference [..] ``#instance(). +# ^ reference [..] B# +# ^ reference [..] C# +# ^^^^^^^^ reference [..] ``#instance(). + end From 48262718b61c3001f70a7c43f5a707c6b5e9d6c2 Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Tue, 6 Sep 2022 12:39:01 +0800 Subject: [PATCH 12/19] fix: Fix source locations for test case DSL. --- rewriter/TestCase.cc | 4 +- test/scip/testdata/test_case.rb | 64 ++++++++++++++++ test/scip/testdata/test_case.snapshot.rb | 93 ++++++++++++++++++++++++ 3 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 test/scip/testdata/test_case.rb create mode 100644 test/scip/testdata/test_case.snapshot.rb diff --git a/rewriter/TestCase.cc b/rewriter/TestCase.cc index b413dc369..9fec885ce 100644 --- a/rewriter/TestCase.cc +++ b/rewriter/TestCase.cc @@ -40,7 +40,7 @@ void TestCase::run(core::MutableContext ctx, ast::ClassDef *klass) { auto snake_case_name = absl::StrReplaceAll(arg0->asString().toString(ctx), {{" ", "_"}}); auto name = ctx.state.enterNameUTF8("test_" + snake_case_name); - auto method = ast::MK::SyntheticMethod0(loc, loc, loc, name, std::move(block->body)); + auto method = ast::MK::SyntheticMethod0(loc, loc, arg0->loc, name, std::move(block->body)); auto method_with_sig = ast::MK::InsSeq1(method.loc(), ast::MK::SigVoid(method.loc(), {}), std::move(method)); stats.emplace_back(std::move(method_with_sig)); @@ -55,7 +55,7 @@ void TestCase::run(core::MutableContext ctx, ast::ClassDef *klass) { auto block = send->block(); auto method_name = send->fun == core::Names::setup() ? core::Names::initialize() : core::Names::teardown(); - auto method = ast::MK::SyntheticMethod0(loc, loc, loc, method_name, std::move(block->body)); + auto method = ast::MK::SyntheticMethod0(loc, loc, send->funLoc, method_name, std::move(block->body)); auto method_with_sig = ast::MK::InsSeq1(method.loc(), ast::MK::SigVoid(method.loc(), {}), std::move(method)); diff --git a/test/scip/testdata/test_case.rb b/test/scip/testdata/test_case.rb new file mode 100644 index 000000000..c2e961ee2 --- /dev/null +++ b/test/scip/testdata/test_case.rb @@ -0,0 +1,64 @@ +# typed: strict + +class ActiveSupport::TestCase +end + +class MyTest < ActiveSupport::TestCase + extend T::Sig + # Helper instance method + sig { params(test: T.untyped).returns(T::Boolean) } + def assert(test) + test ? true : false + end + + # Helper method to direct calls to `test` instead of Kernel#test + sig { params(args: T.untyped, block: T.nilable(T.proc.void)).void } + def self.test(*args, &block) + end + + setup do + @a = T.let(1, Integer) + end + + test "valid method call" do + end + + test "block is evaluated in the context of an instance" do + assert true + end +end + +class NoMatchTest < ActiveSupport::TestCase + extend T::Sig + + sig { params(block: T.proc.void).void } + def self.setup(&block); end + + sig { params(block: T.proc.void).void } + def self.teardown(&block); end +end + +class NoParentClass + extend T::Sig + + sig { params(block: T.proc.void).void } + def self.setup(&block); end + + sig { params(block: T.proc.void).void } + def self.teardown(&block); end + + sig { params(a: T.untyped, b: T.untyped).void } + def assert_equal(a, b); end + + setup do + @a = T.let(1, Integer) + end + + test "it works" do + assert_equal 1, @a + end + + teardown do + @a = 5 + end +end diff --git a/test/scip/testdata/test_case.snapshot.rb b/test/scip/testdata/test_case.snapshot.rb new file mode 100644 index 000000000..59d5ad9e6 --- /dev/null +++ b/test/scip/testdata/test_case.snapshot.rb @@ -0,0 +1,93 @@ + # typed: strict + + class ActiveSupport::TestCase +# ^^^^^^^^^^^^^ reference [..] ActiveSupport# +# ^^^^^^^^ definition [..] ActiveSupport#TestCase# + end + + class MyTest < ActiveSupport::TestCase +# ^^^^^^ definition [..] MyTest# +# ^^^^^^^^^^^^^ reference [..] ActiveSupport# +# ^^^^^^^^ definition [..] ActiveSupport#TestCase# + extend T::Sig + # Helper instance method + sig { params(test: T.untyped).returns(T::Boolean) } +# ^^^^^^^ reference [..] T#Boolean. + def assert(test) +# ^^^^^^ definition [..] MyTest#assert(). +# ^^^^ definition local 1~#2774883451 + test ? true : false + end + + # Helper method to direct calls to `test` instead of Kernel#test + sig { params(args: T.untyped, block: T.nilable(T.proc.void)).void } +# ^^^^ reference [..] `>`#void(). + def self.test(*args, &block) +# ^^^^ definition [..] ``#test(). + end + + setup do +# ^^^^^ definition [..] MyTest#initialize(). + @a = T.let(1, Integer) + end + + test "valid method call" do +# ^^^^^^^^^^^^^^^^^^^ definition [..] MyTest#test_valid_method_call(). + end + + test "block is evaluated in the context of an instance" do +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] MyTest#test_block_is_evaluated_in_the_context_of_an_instance(). + assert true + end + end + + class NoMatchTest < ActiveSupport::TestCase +# ^^^^^^^^^^^ definition [..] NoMatchTest# +# ^^^^^^^^^^^^^ reference [..] ActiveSupport# +# ^^^^^^^^ definition [..] ActiveSupport#TestCase# + extend T::Sig + + sig { params(block: T.proc.void).void } +# ^^^^ reference [..] `>`#void(). + def self.setup(&block); end +# ^^^^^ definition [..] ``#setup(). + + sig { params(block: T.proc.void).void } +# ^^^^ reference [..] `>`#void(). + def self.teardown(&block); end +# ^^^^^^^^ definition [..] ``#teardown(). + end + + class NoParentClass +# ^^^^^^^^^^^^^ definition [..] NoParentClass# + extend T::Sig + + sig { params(block: T.proc.void).void } +# ^^^^ reference [..] `>`#void(). + def self.setup(&block); end +# ^^^^^ definition [..] ``#setup(). + + sig { params(block: T.proc.void).void } +# ^^^^ reference [..] `>`#void(). + def self.teardown(&block); end +# ^^^^^^^^ definition [..] ``#teardown(). + + sig { params(a: T.untyped, b: T.untyped).void } + def assert_equal(a, b); end +# ^^^^^^^^^^^^ definition [..] NoParentClass#assert_equal(). + + setup do +# ^^^^^ definition [..] NoParentClass#initialize(). + @a = T.let(1, Integer) + end + + test "it works" do +# ^^^^^^^^^^ definition [..] NoParentClass#test_it_works(). + assert_equal 1, @a + end + + teardown do +# ^^^^^^^^ definition [..] NoParentClass#teardown(). + @a = 5 + end + end From ef4bed28c25c744a7f7b22dccfe892506f1d8ece Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Tue, 6 Sep 2022 12:48:16 +0800 Subject: [PATCH 13/19] fix: Fix source locations for minitest DSL. --- rewriter/Minitest.cc | 9 +++++---- test/scip/testdata/minitest.snapshot.rb | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/rewriter/Minitest.cc b/rewriter/Minitest.cc index c97ab7ad7..409df6f87 100644 --- a/rewriter/Minitest.cc +++ b/rewriter/Minitest.cc @@ -193,7 +193,8 @@ ast::ExpressionPtr runUnderEach(core::MutableContext ctx, core::NameRef eachName if (send->fun == core::Names::it() && send->numPosArgs() == 1 && send->hasBlock() && send->block()->args.size() == 0) { // we use this for the name of our test - auto argString = to_s(ctx, send->getPosArg(0)); + auto &arg0 = send->getPosArg(0); + auto argString = to_s(ctx, arg0); auto name = ctx.state.enterNameUTF8(""); // pull constants out of the block @@ -221,7 +222,7 @@ ast::ExpressionPtr runUnderEach(core::MutableContext ctx, core::NameRef eachName send->loc.copyWithZeroLength(), move(blk)); // put that into a method def named the appropriate thing auto method = - addSigVoid(ast::MK::SyntheticMethod0(send->loc, send->loc, send->loc, move(name), move(each))); + addSigVoid(ast::MK::SyntheticMethod0(send->loc, send->loc, arg0.loc(), move(name), move(each))); // add back any moved constants return constantMover.addConstantsToExpression(send->loc, move(method)); } @@ -357,7 +358,7 @@ ast::ExpressionPtr runSingle(core::MutableContext ctx, bool isClass, ast::Send * auto name = send->fun == core::Names::after() ? core::Names::afterAngles() : core::Names::initialize(); ConstantMover constantMover; ast::TreeWalk::apply(ctx, constantMover, block->body); - auto method = addSigVoid(ast::MK::SyntheticMethod0(send->loc, send->loc, send->loc, name, + auto method = addSigVoid(ast::MK::SyntheticMethod0(send->loc, send->loc, send->funLoc, name, prepareBody(ctx, isClass, std::move(block->body)))); return constantMover.addConstantsToExpression(send->loc, move(method)); } @@ -388,7 +389,7 @@ ast::ExpressionPtr runSingle(core::MutableContext ctx, bool isClass, ast::Send * ast::TreeWalk::apply(ctx, constantMover, block->body); auto name = ctx.state.enterNameUTF8(""); const bool bodyIsClass = false; - auto method = addSigVoid(ast::MK::SyntheticMethod0(send->loc, send->loc, send->loc, std::move(name), + auto method = addSigVoid(ast::MK::SyntheticMethod0(send->loc, send->loc, arg.loc(), std::move(name), prepareBody(ctx, bodyIsClass, std::move(block->body)))); method = ast::MK::InsSeq1(send->loc, send->getPosArg(0).deepCopy(), move(method)); return constantMover.addConstantsToExpression(send->loc, move(method)); diff --git a/test/scip/testdata/minitest.snapshot.rb b/test/scip/testdata/minitest.snapshot.rb index 51762b6a3..eaaf6cc6c 100644 --- a/test/scip/testdata/minitest.snapshot.rb +++ b/test/scip/testdata/minitest.snapshot.rb @@ -6,19 +6,19 @@ def outside_method end it "works outside" do -# ^^^ definition [..] MyTest#``(). +# ^^^^^^^^^^^^^^^ definition [..] MyTest#``(). outside_method end it "allows constants inside of IT" do -# ^^^^^^^ definition [..] MyTest#``(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] MyTest#``(). CONST = 10 # ^^^^^ definition [..] MyTest#CONST. # ^^^^^^^^^^ reference [..] Kernel# end it "allows let-ed constants inside of IT" do -# ^^^^^^^^^^^ definition [..] MyTest#``(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] MyTest#``(). C2 = T.let(10, Integer) # ^^ definition [..] MyTest#C2. # ^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Kernel# @@ -26,11 +26,11 @@ def outside_method end it "allows path constants inside of IT" do +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] MyTest#``(). C3 = Mod::C # ^^ definition [..] MyTest#C3. # ^^^ reference [..] Mod# # ^ reference [..] Mod#C# -# ^^^^ definition [..] MyTest#``(). C3.new end @@ -41,7 +41,7 @@ def inside_method end it "works inside" do -# ^^^^^^^^^^^^^^^^^^^^^ definition [..] MyTest#``#``(). +# ^^^^^^^^^^^^^^ definition [..] MyTest#``#``(). outside_method inside_method end @@ -51,13 +51,13 @@ def instance_helper; end # ^^^^^^^^^^^^^^^ definition [..] MyTest#instance_helper(). before do -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] MyTest#initialize(). +# ^^^^^^ definition [..] MyTest#initialize(). @foo = T.let(3, Integer) instance_helper end it 'can read foo' do -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] MyTest#``(). +# ^^^^^^^^^^^^^^ definition [..] MyTest#``(). T.assert_type!(@foo, Integer) instance_helper end @@ -69,8 +69,8 @@ def self.random_method describe Object do # ^^^^^^ definition [..] MyTest#``# it Object do -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] MyTest#``#``(). -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] MyTest#``#``(). +# ^^^^^^ definition [..] MyTest#``#``(). +# ^^^^^^ definition [..] MyTest#``#``(). # ^^^^^^ reference [..] Object# end it Object do @@ -91,7 +91,7 @@ def self.it(*args) describe "a non-ideal situation" do # ^^^^^^^^^^^^^^^^^^^^^^^ definition [..] MyTest#``# it "contains nested describes" do -# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] MyTest#``#``(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] MyTest#``#``(). describe "nobody should write this but we should still parse it" do # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] MyTest#``#``# end From 0e5115067e889968dcfba9781c4349bf98cebd30 Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Tue, 6 Sep 2022 18:42:07 +0800 Subject: [PATCH 14/19] test: Add test for encrypted_prop + minor output cleanup. --- scip_indexer/SCIPIndexer.cc | 37 +++++++++++--- test/scip/testdata/encrypted_prop.rb | 21 ++++++++ test/scip/testdata/encrypted_prop.snapshot.rb | 50 +++++++++++++++++++ 3 files changed, 100 insertions(+), 8 deletions(-) create mode 100644 test/scip/testdata/encrypted_prop.rb create mode 100644 test/scip/testdata/encrypted_prop.snapshot.rb diff --git a/scip_indexer/SCIPIndexer.cc b/scip_indexer/SCIPIndexer.cc index 31cfd41a9..7a37b14b2 100644 --- a/scip_indexer/SCIPIndexer.cc +++ b/scip_indexer/SCIPIndexer.cc @@ -167,6 +167,10 @@ bool isSorbetInternal(const core::GlobalState &gs, core::SymbolRef sym) { if (klass == core::Symbols::Sorbet_Private() || klass == core::Symbols::T() || klass == classT) { return true; } + auto name = klass.data(gs)->name; + if (name == core::Names::Constants::Opus()) { + return true; + } } visited.insert(sym); sym = sym.owner(gs); @@ -231,6 +235,11 @@ class NamedSymbolRef final { return lhs.selfOrOwner == rhs.selfOrOwner && lhs.name == rhs.name; } + friend bool operator<(const NamedSymbolRef &lhs, const NamedSymbolRef &rhs) { + return lhs.selfOrOwner.rawId() < rhs.selfOrOwner.rawId() || + (lhs.selfOrOwner == rhs.selfOrOwner && lhs.name.rawId() < rhs.name.rawId()); + } + template friend H AbslHashValue(H h, const NamedSymbolRef &c) { return H::combine(std::move(h), c.selfOrOwner, c.name); } @@ -1236,14 +1245,26 @@ class CFGTraversal final { // Sort for determinism fast_sort(todo, [&](const SymbolWithLoc &p1, const SymbolWithLoc &p2) -> bool { if (p1.second.beginPos() == p2.second.beginPos()) { - // TODO: This code path is hit when there is a module_function on top of a sig. - // In that case, the 'T' and 'X' in 'T::X' in a sig end up with two occurrences each. - // We should check if this is a Sorbet bug or deliberate. - ENFORCE(p1.first == p2.first, - "found different symbols at same location in {}, source:\n{}\nsym1 = {}\nsym2 = {}\n", - file.data(gs).path(), core::Loc(file, p1.second).toString(gs), p1.first.showRaw(gs), - p2.first.showRaw(gs)); - foundDupes = true; + if (p1.first == p2.first) { + foundDupes = true; + } else { + // This code path is hit when trying to use encrypted_prop -- that creates two + // classes ::Opus and ::Opus::DB::Model with the same source locations as the declaration. + // + // It is also hit when a module_function is on top of sig, in which case, + // the 'T' and the 'X' in 'T::X' end up with two occurrences each. This latter + // example seems like a bug though. + return p1.first < p2.first; + } + // return p1.first.showRaw(gs) < p2.first.showRaw(gs); + // // TODO: This code path is hit when there is a module_function on top of a sig. + // // In that case, the 'T' and 'X' in 'T::X' in a sig end up with two occurrences each. + // // We should check if this is a Sorbet bug or deliberate. + // ENFORCE(p1.first == p2.first, + // "found different symbols at same location in {}, source:\n{}\nsym1 = {}\nsym2 = {}\n", + // file.data(gs).path(), core::Loc(file, p1.second).toString(gs), p1.first.showRaw(gs), + // p2.first.showRaw(gs)); + // foundDupes = true; } return p1.second.beginPos() < p2.second.beginPos(); }); diff --git a/test/scip/testdata/encrypted_prop.rb b/test/scip/testdata/encrypted_prop.rb new file mode 100644 index 000000000..b1e1c7dcd --- /dev/null +++ b/test/scip/testdata/encrypted_prop.rb @@ -0,0 +1,21 @@ +# typed: true + +# Minimal stub of Chalk implementation to support encrypted_prop +class Chalk::ODM::Document +end +class Opus::DB::Model::Mixins::Encryptable::EncryptedValue < Chalk::ODM::Document +end + +class EncryptedProp + include T::Props + def self.encrypted_prop(opts={}); end + encrypted_prop :foo + encrypted_prop :bar, migrating: true, immutable: true +end + + +def f + EncryptedProp.new.foo = "hello" + EncryptedProp.new.foo = nil + return EncryptedProp.new.encrypted_foo +end diff --git a/test/scip/testdata/encrypted_prop.snapshot.rb b/test/scip/testdata/encrypted_prop.snapshot.rb new file mode 100644 index 000000000..143bfa17b --- /dev/null +++ b/test/scip/testdata/encrypted_prop.snapshot.rb @@ -0,0 +1,50 @@ + # typed: true + + # Minimal stub of Chalk implementation to support encrypted_prop + class Chalk::ODM::Document +# ^^^^^ reference [..] Chalk# +# ^^^ reference [..] Chalk#ODM# +# ^^^^^^^^ definition [..] Chalk#ODM#Document# + end + class Opus::DB::Model::Mixins::Encryptable::EncryptedValue < Chalk::ODM::Document +# ^^^^ reference [..] Opus# +# ^^ reference [..] Opus#DB# +# ^^^^^ reference [..] Opus#DB#Model# +# ^^^^^^ reference [..] Opus#DB#Model#Mixins# +# ^^^^^^^^^^^ reference [..] Opus#DB#Model#Mixins#Encryptable# +# ^^^^^^^^^^^^^^ definition [..] Opus#DB#Model#Mixins#Encryptable#EncryptedValue# +# ^^^^^ reference [..] Chalk# +# ^^^ reference [..] Chalk#ODM# +# ^^^^^^^^ definition [..] Chalk#ODM#Document# + end + + class EncryptedProp +# ^^^^^^^^^^^^^ definition [..] EncryptedProp# + include T::Props + def self.encrypted_prop(opts={}); end +# ^^^^^^^^^^^^^^ definition [..] ``#encrypted_prop(). + encrypted_prop :foo +# ^^^^^^^^^^^^^^^^^^^ reference [..] String# +# ^^^ definition [..] EncryptedProp#`encrypted_foo=`(). +# ^^^ definition [..] EncryptedProp#`foo=`(). +# ^^^ definition [..] EncryptedProp#encrypted_foo(). +# ^^^ definition [..] EncryptedProp#foo(). + encrypted_prop :bar, migrating: true, immutable: true +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] String# +# ^^^ definition [..] EncryptedProp#bar(). +# ^^^ definition [..] EncryptedProp#encrypted_bar(). + end + + + def f +# ^ definition [..] Object#f(). + EncryptedProp.new.foo = "hello" +# ^^^^^^^^^^^^^ reference [..] EncryptedProp# +# ^^^^^ reference [..] EncryptedProp#`foo=`(). + EncryptedProp.new.foo = nil +# ^^^^^^^^^^^^^ reference [..] EncryptedProp# +# ^^^^^ reference [..] EncryptedProp#`foo=`(). + return EncryptedProp.new.encrypted_foo +# ^^^^^^^^^^^^^ reference [..] EncryptedProp# +# ^^^^^^^^^^^^^ reference [..] EncryptedProp#encrypted_foo(). + end From dec21128b91e54479d04212c71c7193cbd6d7132 Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Tue, 6 Sep 2022 19:12:01 +0800 Subject: [PATCH 15/19] fix: Fix source location for module_function. --- rewriter/ModuleFunction.cc | 3 ++- .../testdata/{types.rb => module_function.rb} | 7 ++----- .../scip/testdata/module_function.snapshot.rb | 14 +++++++++++++ test/scip/testdata/types.snapshot.rb | 21 ------------------- 4 files changed, 18 insertions(+), 27 deletions(-) rename test/scip/testdata/{types.rb => module_function.rb} (59%) create mode 100644 test/scip/testdata/module_function.snapshot.rb delete mode 100644 test/scip/testdata/types.snapshot.rb diff --git a/rewriter/ModuleFunction.cc b/rewriter/ModuleFunction.cc index 9745ca281..196ee9955 100644 --- a/rewriter/ModuleFunction.cc +++ b/rewriter/ModuleFunction.cc @@ -138,7 +138,8 @@ vector ModuleFunction::run(core::MutableContext ctx, ast::Se ast::MethodDef::ARGS_store args; args.emplace_back(ast::MK::RestArg(loc, ast::MK::Local(loc, core::Names::arg0()))); args.emplace_back(ast::make_expression(loc, ast::MK::Local(loc, core::Names::blkArg()))); - auto methodDef = ast::MK::SyntheticMethod(loc, loc, loc, methodName, std::move(args), ast::MK::EmptyTree()); + auto methodDef = + ast::MK::SyntheticMethod(loc, loc, lit->loc, methodName, std::move(args), ast::MK::EmptyTree()); ast::cast_tree_nonnull(methodDef).flags.isSelfMethod = true; stats.emplace_back(std::move(methodDef)); } else { diff --git a/test/scip/testdata/types.rb b/test/scip/testdata/module_function.rb similarity index 59% rename from test/scip/testdata/types.rb rename to test/scip/testdata/module_function.rb index f7dd8cc5c..8da0c6e48 100644 --- a/test/scip/testdata/types.rb +++ b/test/scip/testdata/module_function.rb @@ -1,13 +1,10 @@ # typed: true -def f() - T.let(true, T::Boolean) -end - module M - module_function sig { returns(T::Boolean) } def b true end + + module_function :b end diff --git a/test/scip/testdata/module_function.snapshot.rb b/test/scip/testdata/module_function.snapshot.rb new file mode 100644 index 000000000..2379b31e5 --- /dev/null +++ b/test/scip/testdata/module_function.snapshot.rb @@ -0,0 +1,14 @@ + # typed: true + + module M +# ^ definition [..] M# + sig { returns(T::Boolean) } +# ^^^^^^^ reference [..] T#Boolean. + def b +# ^ definition [..] M#b(). + true + end + + module_function :b +# ^^ definition [..] ``#b(). + end diff --git a/test/scip/testdata/types.snapshot.rb b/test/scip/testdata/types.snapshot.rb deleted file mode 100644 index 43a562e89..000000000 --- a/test/scip/testdata/types.snapshot.rb +++ /dev/null @@ -1,21 +0,0 @@ - # typed: true - - def f() -# ^ definition [..] Object#f(). - T.let(true, T::Boolean) -# ^ reference [..] T# -# ^^^^^^^ reference [..] T#Boolean. - end - - module M -# ^ definition [..] M# - module_function - sig { returns(T::Boolean) } -# ^^^^^^^ reference [..] T#Boolean. -# ^^^^^^^ reference [..] T#Boolean. - def b -# ^ definition [..] M#b(). -# ^ definition [..] ``#b(). - true - end - end From 0af7b920dd0dbc24805321df24b98b3b794721e5 Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Tue, 6 Sep 2022 19:37:11 +0800 Subject: [PATCH 16/19] cleanup: De-duplicate symbol references for same location. --- scip_indexer/SCIPIndexer.cc | 22 ++++++++++++++++++++-- test/scip/testdata/struct.snapshot.rb | 12 ++---------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/scip_indexer/SCIPIndexer.cc b/scip_indexer/SCIPIndexer.cc index 7a37b14b2..7770855bb 100644 --- a/scip_indexer/SCIPIndexer.cc +++ b/scip_indexer/SCIPIndexer.cc @@ -505,6 +505,8 @@ class SCIPState { // map in debug, so keeping it a map. UnorderedMap, uint32_t> localOccurrenceCache; + UnorderedSet> symbolOccurrenceCache; + GemMetadata gemMetadata; public: @@ -656,6 +658,17 @@ class SCIPState { return true; } + bool cacheOccurrence(const core::GlobalState &gs, core::Loc loc, NamedSymbolRef sym, int32_t symbolRoles) { + // Optimization: + // Avoid emitting duplicate def/refs for symbols. + // This can happen with constructs like: + // prop :foo, String + // Without this optimization, there are 4 occurrences for String + // emitted for the same source range. + auto [_, inserted] = this->symbolOccurrenceCache.insert({sym, loc, symbolRoles}); + return !inserted; + } + public: absl::Status saveDefinition(const core::GlobalState &gs, core::FileRef file, OwnedLocal occ, core::TypePtr type) { if (this->cacheOccurrence(gs, file, occ, scip::SymbolRole::Definition)) { @@ -676,7 +689,8 @@ class SCIPState { // TODO(varun): Should we always pass in the location instead of sometimes only? absl::Status saveDefinition(const core::GlobalState &gs, core::FileRef file, NamedSymbolRef symRef, std::optional loc = std::nullopt) { - // TODO:(varun) Should we cache here too to avoid emitting duplicate definitions? + // In practice, there doesn't seem to be any situation which triggers + // a duplicate definition being emitted, so skip calling cacheOccurrence here. scip::Symbol symbol; auto occLoc = loc.has_value() ? core::Loc(file, loc.value()) : symRef.symbolLoc(gs, file); auto status = symRef.symbolForExpr(gs, this->gemMetadata, symbol, occLoc); @@ -718,6 +732,10 @@ class SCIPState { return absl::OkStatus(); } } + auto loc = core::Loc(ctx.file, occLoc); + if (this->cacheOccurrence(ctx, loc, symRef, symbol_roles)) { + return absl::OkStatus(); + } auto &gs = ctx.state; auto file = ctx.file; // TODO:(varun) Should we cache here to to avoid emitting duplicate references? @@ -736,7 +754,7 @@ class SCIPState { case Kind::UndeclaredField: case Kind::DeclaredField: if (overrideType.has_value()) { - overrideDocs = symRef.docStrings(gs, overrideType.value(), core::Loc(file, occLoc)); + overrideDocs = symRef.docStrings(gs, overrideType.value(), loc); } } this->saveReferenceImpl(gs, file, symbolString, overrideDocs, occLoc, symbol_roles); diff --git a/test/scip/testdata/struct.snapshot.rb b/test/scip/testdata/struct.snapshot.rb index 2ac13f43d..9e74c3a6c 100644 --- a/test/scip/testdata/struct.snapshot.rb +++ b/test/scip/testdata/struct.snapshot.rb @@ -7,22 +7,14 @@ class S < T::Struct # ^^^^^^ definition [..] S#initialize(). # ^^^^^^ definition [..] T#Struct# prop :prop_i, Integer -# ^^^^^^ definition [..] S#`prop_i=`(). # ^^^^^^ definition [..] S#prop_i(). -# ^^^^^^^ reference [..] Integer# -# ^^^^^^^ reference [..] Integer# -# ^^^^^^^ reference [..] Integer# -# ^^^^^^^ reference [..] Integer# +# ^^^^^^ definition [..] S#`prop_i=`(). # ^^^^^^^ reference [..] Integer# const :const_s, T.nilable(String) # ^^^^^^^ definition [..] S#const_s(). -# ^^^^^^ reference [..] String# -# ^^^^^^ reference [..] String# # ^^^^^^ reference [..] String# const :const_f, Float, default: 0.5 # ^^^^^^^ definition [..] S#const_f(). -# ^^^^^ reference [..] Float# -# ^^^^^ reference [..] Float# # ^^^^^ reference [..] Float# end @@ -53,9 +45,9 @@ def f POINT = Struct.new(:x, :y) do #^^^^^ definition [..] POINT# +#^^^^^^^^^^^^^^^^^^^^ definition local 5~#119448696 #^^^^^^^^^^^^^^^^^^^^ definition [..] Struct# #^^^^^^^^^^^^^^^^^^^^ definition [..] POINT#initialize(). -#^^^^^^^^^^^^^^^^^^^^ definition local 5~#119448696 # ^ definition [..] POINT#x(). # ^ definition [..] POINT#`x=`(). # ^ reference [..] BasicObject# From b8a0e8a42564ea3dbb075f958da4e84ba77da4a3 Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Tue, 6 Sep 2022 19:42:19 +0800 Subject: [PATCH 17/19] test: Add test for prop. --- test/scip/testdata/prop.rb | 105 +++++++++++ test/scip/testdata/prop.snapshot.rb | 261 ++++++++++++++++++++++++++++ 2 files changed, 366 insertions(+) create mode 100644 test/scip/testdata/prop.rb create mode 100644 test/scip/testdata/prop.snapshot.rb diff --git a/test/scip/testdata/prop.rb b/test/scip/testdata/prop.rb new file mode 100644 index 000000000..1fc5baed6 --- /dev/null +++ b/test/scip/testdata/prop.rb @@ -0,0 +1,105 @@ +# typed: true + +class SomeODM + extend T::Sig + include T::Props + + prop :foo, String + + sig {returns(T.nilable(String))} + def foo2; T.cast(T.unsafe(nil), T.nilable(String)); end + sig {params(arg0: String).returns(String)} + def foo2=(arg0); T.cast(nil, String); end +end + +class ForeignClass +end + +class AdvancedODM + include T::Props + prop :default, String, default: "" + prop :t_nilable, T.nilable(String) + + prop :array, Array + prop :t_array, T::Array[String] + prop :hash_of, T::Hash[Symbol, String] + + prop :const_explicit, String, immutable: true + const :const, String + + prop :enum_prop, String, enum: ["hello", "goodbye"] + + prop :foreign_lazy, String, foreign: -> {ForeignClass} + prop :foreign_proc, String, foreign: proc {ForeignClass} + prop :foreign_invalid, String, foreign: proc { :not_a_type } + + prop :ifunset, String, ifunset: '' + prop :ifunset_nilable, T.nilable(String), ifunset: '' + + prop :empty_hash_rules, String, {} + prop :hash_rules, String, { enum: ["hello", "goodbye" ] } +end + +class PropHelpers + include T::Props + def self.token_prop(opts={}); end + def self.created_prop(opts={}); end + token_prop + created_prop +end + +class PropHelpers2 + include T::Props + def self.timestamped_token_prop(opts={}); end + def self.created_prop(opts={}); end + timestamped_token_prop + created_prop(immutable: true) +end + +def main + SomeODM.new.foo + SomeODM.new.foo = 'b' + SomeODM.new.foo2 + SomeODM.new.foo2 = 'b' + + AdvancedODM.new.default + AdvancedODM.new.t_nilable + + AdvancedODM.new.t_array + AdvancedODM.new.hash_of + + AdvancedODM.new.const_explicit + AdvancedODM.new.const_explicit = 'b' + AdvancedODM.new.const + AdvancedODM.new.const = 'b' + + AdvancedODM.new.enum_prop + AdvancedODM.new.enum_prop = "hello" + + AdvancedODM.new.foreign_ + AdvancedODM.new.foreign_ + AdvancedODM.new.foreign_lazy_ + + # Check that the method still exists even if we can't parse the type + AdvancedODM.new.foreign_invalid_ + + PropHelpers.new.token + PropHelpers.new.token = "tok_token" + PropHelpers.new.token = nil + + PropHelpers.new.created + PropHelpers.new.created = 0.0 + PropHelpers.new.created = nil + + PropHelpers2.new.token + PropHelpers2.new.token = "tok_token" + PropHelpers2.new.token = nil + + PropHelpers2.new.created + PropHelpers2.new.created = 0.0 + + AdvancedODM.new.ifunset + AdvancedODM.new.ifunset_nilable + AdvancedODM.new.ifunset = nil + AdvancedODM.new.ifunset_nilable = nil +end diff --git a/test/scip/testdata/prop.snapshot.rb b/test/scip/testdata/prop.snapshot.rb new file mode 100644 index 000000000..b915d90fb --- /dev/null +++ b/test/scip/testdata/prop.snapshot.rb @@ -0,0 +1,261 @@ + # typed: true + + class SomeODM +# ^^^^^^^ definition [..] SomeODM# + extend T::Sig + include T::Props + + prop :foo, String +# ^^^ definition [..] SomeODM#foo(). +# ^^^ definition [..] SomeODM#`foo=`(). +# ^^^^^^ reference [..] String# + + sig {returns(T.nilable(String))} +# ^^^^^^ reference [..] String# + def foo2; T.cast(T.unsafe(nil), T.nilable(String)); end +# ^^^^ definition [..] SomeODM#foo2(). +# ^ reference [..] T# +# ^^^^^^ reference [..] ``#unsafe(). +# ^ reference [..] T# +# ^^^^^^^ reference [..] ``#nilable(). +# ^^^^^^ reference [..] String# + sig {params(arg0: String).returns(String)} +# ^^^^^^ reference [..] String# +# ^^^^^^ reference [..] String# + def foo2=(arg0); T.cast(nil, String); end +# ^^^^^ definition [..] SomeODM#`foo2=`(). +# ^^^^^^ reference [..] String# + end + + class ForeignClass +# ^^^^^^^^^^^^ definition [..] ForeignClass# + end + + class AdvancedODM +# ^^^^^^^^^^^ definition [..] AdvancedODM# + include T::Props + prop :default, String, default: "" +# ^^^^^^^ definition [..] AdvancedODM#default(). +# ^^^^^^^ definition [..] AdvancedODM#`default=`(). +# ^^^^^^ reference [..] String# + prop :t_nilable, T.nilable(String) +# ^^^^^^^^^ definition [..] AdvancedODM#t_nilable(). +# ^^^^^^^^^ definition [..] AdvancedODM#`t_nilable=`(). +# ^^^^^^ reference [..] String# + + prop :array, Array +# ^^^^^ definition [..] AdvancedODM#`array=`(). +# ^^^^^ definition [..] AdvancedODM#array(). +# ^^^^^ reference [..] Array# + prop :t_array, T::Array[String] +# ^^^^^^^ definition [..] AdvancedODM#t_array(). +# ^^^^^^^ definition [..] AdvancedODM#`t_array=`(). +# ^^^^^^ reference [..] String# + prop :hash_of, T::Hash[Symbol, String] +# ^^^^^^^ definition [..] AdvancedODM#hash_of(). +# ^^^^^^^ definition [..] AdvancedODM#`hash_of=`(). +# ^^^^^^ reference [..] Symbol# +# ^^^^^^ reference [..] String# + + prop :const_explicit, String, immutable: true +# ^^^^^^^^^^^^^^ definition [..] AdvancedODM#const_explicit(). +# ^^^^^^ reference [..] String# + const :const, String +# ^^^^^ definition [..] AdvancedODM#const(). +# ^^^^^^ reference [..] String# + + prop :enum_prop, String, enum: ["hello", "goodbye"] +# ^^^^^^^^^ definition [..] AdvancedODM#`enum_prop=`(). +# ^^^^^^^^^ definition [..] AdvancedODM#enum_prop(). +# ^^^^^^ reference [..] String# + + prop :foreign_lazy, String, foreign: -> {ForeignClass} +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Boolean. +# ^^^^^^^^^^^^ definition [..] AdvancedODM#`foreign_lazy_!`(). +# ^^^^^^^^^^^^ definition [..] AdvancedODM#foreign_lazy_(). +# ^^^^^^^^^^^^ definition [..] AdvancedODM#`foreign_lazy=`(). +# ^^^^^^^^^^^^ definition [..] AdvancedODM#foreign_lazy(). +# ^^^^^^ reference [..] String# +# ^^ reference [..] Kernel# +# ^^^^^^^^^^^^ reference [..] ForeignClass# + prop :foreign_proc, String, foreign: proc {ForeignClass} +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Boolean. +# ^^^^^^^^^^^^ definition [..] AdvancedODM#`foreign_proc_!`(). +# ^^^^^^^^^^^^ definition [..] AdvancedODM#foreign_proc_(). +# ^^^^^^^^^^^^ definition [..] AdvancedODM#`foreign_proc=`(). +# ^^^^^^^^^^^^ definition [..] AdvancedODM#foreign_proc(). +# ^^^^^^ reference [..] String# +# ^^^^^^^^^^^^ reference [..] ForeignClass# + prop :foreign_invalid, String, foreign: proc { :not_a_type } +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] T#Boolean. +# ^^^^^^^^^^^^^^^ definition [..] AdvancedODM#`foreign_invalid_!`(). +# ^^^^^^^^^^^^^^^ definition [..] AdvancedODM#foreign_invalid_(). +# ^^^^^^^^^^^^^^^ definition [..] AdvancedODM#`foreign_invalid=`(). +# ^^^^^^^^^^^^^^^ definition [..] AdvancedODM#foreign_invalid(). +# ^^^^^^ reference [..] String# + + prop :ifunset, String, ifunset: '' +# ^^^^^^^ definition [..] AdvancedODM#ifunset(). +# ^^^^^^^ definition [..] AdvancedODM#`ifunset=`(). +# ^^^^^^ reference [..] String# + prop :ifunset_nilable, T.nilable(String), ifunset: '' +# ^^^^^^^^^^^^^^^ definition [..] AdvancedODM#ifunset_nilable(). +# ^^^^^^^^^^^^^^^ definition [..] AdvancedODM#`ifunset_nilable=`(). +# ^^^^^^ reference [..] String# + + prop :empty_hash_rules, String, {} +# ^^^^^^^^^^^^^^^^ definition [..] AdvancedODM#empty_hash_rules(). +# ^^^^^^^^^^^^^^^^ definition [..] AdvancedODM#`empty_hash_rules=`(). +# ^^^^^^ reference [..] String# + prop :hash_rules, String, { enum: ["hello", "goodbye" ] } +# ^^^^^^^^^^ definition [..] AdvancedODM#`hash_rules=`(). +# ^^^^^^^^^^ definition [..] AdvancedODM#hash_rules(). +# ^^^^^^ reference [..] String# + end + + class PropHelpers +# ^^^^^^^^^^^ definition [..] PropHelpers# + include T::Props + def self.token_prop(opts={}); end +# ^^^^^^^^^^ definition [..] ``#token_prop(). + def self.created_prop(opts={}); end +# ^^^^^^^^^^^^ definition [..] ``#created_prop(). + token_prop +# ^^^^^ definition [..] PropHelpers#`token=`(). +# ^^^^^ definition [..] PropHelpers#token(). +# ^^^^^^^^^^ reference [..] ``#token_prop(). +# ^^^^^^^^^^ reference [..] String# + created_prop +# ^^^^^^^ definition [..] PropHelpers#`created=`(). +# ^^^^^^^ definition [..] PropHelpers#created(). +# ^^^^^^^^^^^^ reference [..] ``#created_prop(). +# ^^^^^^^^^^^^ reference [..] Float# + end + + class PropHelpers2 +# ^^^^^^^^^^^^ definition [..] PropHelpers2# + include T::Props + def self.timestamped_token_prop(opts={}); end +# ^^^^^^^^^^^^^^^^^^^^^^ definition [..] ``#timestamped_token_prop(). + def self.created_prop(opts={}); end +# ^^^^^^^^^^^^ definition [..] ``#created_prop(). + timestamped_token_prop +# ^^^^^^^^^^^^^^^^^^^^^^ reference [..] String# +# ^^^^^^^^^^^^^^^^^^^^^^ reference [..] ``#timestamped_token_prop(). +# ^^^^^ definition [..] PropHelpers2#token(). +# ^^^^^ definition [..] PropHelpers2#`token=`(). + created_prop(immutable: true) +# ^^^^^^^^^^^^ reference [..] ``#created_prop(). +# ^^^^^^^^^^^^^^^^^^^^^^^^ definition [..] PropHelpers2#created(). +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reference [..] Float# + end + + def main +# ^^^^ definition [..] Object#main(). + SomeODM.new.foo +# ^^^^^^^ reference [..] SomeODM# +# ^^^ reference [..] SomeODM#foo(). + SomeODM.new.foo = 'b' +# ^^^^^^^ reference [..] SomeODM# +# ^^^^^ reference [..] SomeODM#`foo=`(). + SomeODM.new.foo2 +# ^^^^^^^ reference [..] SomeODM# +# ^^^^ reference [..] SomeODM#foo2(). + SomeODM.new.foo2 = 'b' +# ^^^^^^^ reference [..] SomeODM# +# ^^^^^^ reference [..] SomeODM#`foo2=`(). + + AdvancedODM.new.default +# ^^^^^^^^^^^ reference [..] AdvancedODM# +# ^^^^^^^ reference [..] AdvancedODM#default(). + AdvancedODM.new.t_nilable +# ^^^^^^^^^^^ reference [..] AdvancedODM# +# ^^^^^^^^^ reference [..] AdvancedODM#t_nilable(). + + AdvancedODM.new.t_array +# ^^^^^^^^^^^ reference [..] AdvancedODM# +# ^^^^^^^ reference [..] AdvancedODM#t_array(). + AdvancedODM.new.hash_of +# ^^^^^^^^^^^ reference [..] AdvancedODM# +# ^^^^^^^ reference [..] AdvancedODM#hash_of(). + + AdvancedODM.new.const_explicit +# ^^^^^^^^^^^ reference [..] AdvancedODM# +# ^^^^^^^^^^^^^^ reference [..] AdvancedODM#const_explicit(). + AdvancedODM.new.const_explicit = 'b' +# ^^^^^^^^^^^ reference [..] AdvancedODM# + AdvancedODM.new.const +# ^^^^^^^^^^^ reference [..] AdvancedODM# +# ^^^^^ reference [..] AdvancedODM#const(). + AdvancedODM.new.const = 'b' +# ^^^^^^^^^^^ reference [..] AdvancedODM# + + AdvancedODM.new.enum_prop +# ^^^^^^^^^^^ reference [..] AdvancedODM# +# ^^^^^^^^^ reference [..] AdvancedODM#enum_prop(). + AdvancedODM.new.enum_prop = "hello" +# ^^^^^^^^^^^ reference [..] AdvancedODM# +# ^^^^^^^^^^^ reference [..] AdvancedODM#`enum_prop=`(). + + AdvancedODM.new.foreign_ +# ^^^^^^^^^^^ reference [..] AdvancedODM# + AdvancedODM.new.foreign_ +# ^^^^^^^^^^^ reference [..] AdvancedODM# + AdvancedODM.new.foreign_lazy_ +# ^^^^^^^^^^^ reference [..] AdvancedODM# +# ^^^^^^^^^^^^^ reference [..] AdvancedODM#foreign_lazy_(). + + # Check that the method still exists even if we can't parse the type + AdvancedODM.new.foreign_invalid_ +# ^^^^^^^^^^^ reference [..] AdvancedODM# +# ^^^^^^^^^^^^^^^^ reference [..] AdvancedODM#foreign_invalid_(). + + PropHelpers.new.token +# ^^^^^^^^^^^ reference [..] PropHelpers# +# ^^^^^ reference [..] PropHelpers#token(). + PropHelpers.new.token = "tok_token" +# ^^^^^^^^^^^ reference [..] PropHelpers# +# ^^^^^^^ reference [..] PropHelpers#`token=`(). + PropHelpers.new.token = nil +# ^^^^^^^^^^^ reference [..] PropHelpers# +# ^^^^^^^ reference [..] PropHelpers#`token=`(). + + PropHelpers.new.created +# ^^^^^^^^^^^ reference [..] PropHelpers# +# ^^^^^^^ reference [..] PropHelpers#created(). + PropHelpers.new.created = 0.0 +# ^^^^^^^^^^^ reference [..] PropHelpers# +# ^^^^^^^^^ reference [..] PropHelpers#`created=`(). + PropHelpers.new.created = nil +# ^^^^^^^^^^^ reference [..] PropHelpers# +# ^^^^^^^^^ reference [..] PropHelpers#`created=`(). + + PropHelpers2.new.token +# ^^^^^^^^^^^^ reference [..] PropHelpers2# +# ^^^^^ reference [..] PropHelpers2#token(). + PropHelpers2.new.token = "tok_token" +# ^^^^^^^^^^^^ reference [..] PropHelpers2# +# ^^^^^^^ reference [..] PropHelpers2#`token=`(). + PropHelpers2.new.token = nil +# ^^^^^^^^^^^^ reference [..] PropHelpers2# +# ^^^^^^^ reference [..] PropHelpers2#`token=`(). + + PropHelpers2.new.created +# ^^^^^^^^^^^^ reference [..] PropHelpers2# +# ^^^^^^^ reference [..] PropHelpers2#created(). + PropHelpers2.new.created = 0.0 +# ^^^^^^^^^^^^ reference [..] PropHelpers2# + + AdvancedODM.new.ifunset +# ^^^^^^^^^^^ reference [..] AdvancedODM# +# ^^^^^^^ reference [..] AdvancedODM#ifunset(). + AdvancedODM.new.ifunset_nilable +# ^^^^^^^^^^^ reference [..] AdvancedODM# +# ^^^^^^^^^^^^^^^ reference [..] AdvancedODM#ifunset_nilable(). + AdvancedODM.new.ifunset = nil +# ^^^^^^^^^^^ reference [..] AdvancedODM# +# ^^^^^^^^^ reference [..] AdvancedODM#`ifunset=`(). + AdvancedODM.new.ifunset_nilable = nil +# ^^^^^^^^^^^ reference [..] AdvancedODM# +# ^^^^^^^^^^^^^^^^^ reference [..] AdvancedODM#`ifunset_nilable=`(). + end From 96ba9fd2ec6d55fda47aa53b11eabae310f69f81 Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Tue, 6 Sep 2022 19:57:10 +0800 Subject: [PATCH 18/19] fix: Fix source location for initialize function. --- rewriter/Prop.cc | 8 ++++---- test/scip/testdata/struct.snapshot.rb | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/rewriter/Prop.cc b/rewriter/Prop.cc index 6cb729b29..cb4d5576c 100644 --- a/rewriter/Prop.cc +++ b/rewriter/Prop.cc @@ -546,7 +546,8 @@ ast::ExpressionPtr ensureWithoutAccessors(const PropInfo &prop, const ast::Send } vector mkTypedInitialize(core::MutableContext ctx, core::LocOffsets klassLoc, - core::LocOffsets klassDeclLoc, const vector &props) { + core::LocOffsets klassDeclLoc, core::LocOffsets klassNameLoc, + const vector &props) { ast::MethodDef::ARGS_store args; ast::Send::ARGS_store sigArgs; args.reserve(props.size()); @@ -597,8 +598,7 @@ vector mkTypedInitialize(core::MutableContext ctx, core::Loc vector result; result.emplace_back(ast::MK::SigVoid(klassDeclLoc, std::move(sigArgs))); - // TODO(varun): What does klassDeclLoc correspond to? - result.emplace_back(ast::MK::SyntheticMethod(klassLoc, klassDeclLoc, klassDeclLoc, core::Names::initialize(), + result.emplace_back(ast::MK::SyntheticMethod(klassLoc, klassDeclLoc, klassNameLoc, core::Names::initialize(), std::move(args), std::move(body))); return result; } @@ -663,7 +663,7 @@ void Prop::run(core::MutableContext ctx, ast::ClassDef *klass) { // we define our synthesized initialize first so that if the user wrote one themselves, it overrides ours. if (wantTypedInitialize(syntacticSuperClass)) { // For direct T::Struct subclasses, we know that seeing no props means the constructor should be zero-arity. - for (auto &stat : mkTypedInitialize(ctx, klass->loc, klass->declLoc, props)) { + for (auto &stat : mkTypedInitialize(ctx, klass->loc, klass->declLoc, klass->name.loc(), props)) { klass->rhs.emplace_back(std::move(stat)); } } diff --git a/test/scip/testdata/struct.snapshot.rb b/test/scip/testdata/struct.snapshot.rb index 9e74c3a6c..562879368 100644 --- a/test/scip/testdata/struct.snapshot.rb +++ b/test/scip/testdata/struct.snapshot.rb @@ -2,9 +2,9 @@ # From Sorbet docs https://sorbet.org/docs/tstruct class S < T::Struct +# ^ definition [..] S#initialize(). # ^ definition [..] S# # ^ reference [..] T# -# ^^^^^^ definition [..] S#initialize(). # ^^^^^^ definition [..] T#Struct# prop :prop_i, Integer # ^^^^^^ definition [..] S#prop_i(). From 8dca7dc54658d02c864e09cb85dd2abfcfb3c2d9 Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Tue, 6 Sep 2022 20:12:22 +0800 Subject: [PATCH 19/19] cleanup: Remove debug print statement + commented out code. --- scip_indexer/SCIPIndexer.cc | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/scip_indexer/SCIPIndexer.cc b/scip_indexer/SCIPIndexer.cc index 7770855bb..04ebce038 100644 --- a/scip_indexer/SCIPIndexer.cc +++ b/scip_indexer/SCIPIndexer.cc @@ -435,7 +435,6 @@ class NamedSymbolRef final { auto method = this->selfOrOwner.asMethodRef().data(gs); auto offset = method->nameLoc; if (!offset.exists() || offset.empty()) { - fmt::print("Missing nameLoc for {}\n", this->showRaw(gs)); return method->loc(); } return core::Loc(file, offset); @@ -1265,6 +1264,7 @@ class CFGTraversal final { if (p1.second.beginPos() == p2.second.beginPos()) { if (p1.first == p2.first) { foundDupes = true; + return false; } else { // This code path is hit when trying to use encrypted_prop -- that creates two // classes ::Opus and ::Opus::DB::Model with the same source locations as the declaration. @@ -1274,15 +1274,6 @@ class CFGTraversal final { // example seems like a bug though. return p1.first < p2.first; } - // return p1.first.showRaw(gs) < p2.first.showRaw(gs); - // // TODO: This code path is hit when there is a module_function on top of a sig. - // // In that case, the 'T' and 'X' in 'T::X' in a sig end up with two occurrences each. - // // We should check if this is a Sorbet bug or deliberate. - // ENFORCE(p1.first == p2.first, - // "found different symbols at same location in {}, source:\n{}\nsym1 = {}\nsym2 = {}\n", - // file.data(gs).path(), core::Loc(file, p1.second).toString(gs), p1.first.showRaw(gs), - // p2.first.showRaw(gs)); - // foundDupes = true; } return p1.second.beginPos() < p2.second.beginPos(); });