What if we did something like this: ``` val getVal...
# arrow-meta
a
What if we did something like this:
Copy code
val getValOrVarKeyword: Scoped<PsiElement> = Scoped(value.getValOrVarKeyword)
r
The Scope already supports nullable KtElement. The scope should never be nullable because when a property is null it should render as a empty string and that is control by the Scope.toString override.
Scopes are a way to destructure a template and tell it based on the
toString
method how to render.
a
attempted editing above ^
r
Even if a class has no annotations has a
@annotationEntries
scope that when rendered produces an empty string. This is necessary so people can compose their templates safely without having to check for
null
inside the templates which will be rather cumbersome since template expressions are hard to read when they spawn more than one line and nullable types chaining tends to nest whenever you want to do something complex
a
@bloder ^
r
@amanda.hinchman-dominguez I don’t understand in which context that code appears, you mean to have a scope reference another scope?
that function is fine if you don’t plan on destructuring
valOrKeyword
with a template but if you do you would use there instead the actual concrete scope that gives you template powers
a
Possibly - for example, in
KtParameter
, we probably want to know of the
valOrVar
r
Copy code
val getValOrVarKeyword: ValOrKeywordScope = ValOrKeywordScope(value.getValOrVarKeyword)
where
ValOrKeywordScope : Scope<KtVarOrKeywordWhatever>
a
Do we want to do that within the scope of
ParameterScope
?
r
whenever we can talk about about a more ocmplete scope of an element we want to use the most concrete Scope
for example if a function is ever mentioned we always want to use FuncScope
r
if we have a quote scope for a KtParameter instead of using
Scope<KtParameter>
we always want to use
ParameterScope
which already extends
Scope<KtParameter>
a
^so we have that
but we want to be able to expose its properties, some of which are
PsiElements
Ah, imran mentioned we don't have a need for that https://github.com/arrow-kt/arrow-meta/pull/100#discussion_r344760427
So as the answer to our original question "Do we need to map PsiElement attributes to Scopes?" Is the answer no?
r
the answer is no because the actual function that gets passed to the user in the quote has two valuable pieces of design:
1. The receiver in that function and
this
pointer is the actual scope so you can access the entire scope without a prefix. 2. The function receives an argument of the
KtElement
type as
it
giving you full access to the entire PSI api of that element including traversal, properties and everything you need,
That is my opinion. I think the sole purpose of scopes is to provide template destructuring capabilities and all methods in their API should be related to rendering properties but not conditional logic or other type of operations that belong in the PSI and that we don’t have to worry about maintaining.
👍 2
a
Okay, that's super helpful, because we was trying to figure out what all we need to be doing
r
We are meeting on Wednesday on our first weekly stand up that @paco is organizing where we will organize everyone’s work and goals for each week
👍 2
b
Could we continue with splitting this cases in scopes then? like:
Copy code
val getValOrVarKeyword: ValOrVarKeywordScope = ValOrVarKeywordScope(value.getValOrVarKeyword)
in my opinion that makes sense
r
Yes, I think the rule of thumb is. Whenever you find an inner element inside a KtElement that is worth a custom scope then create the scope for that and use the custom scope instead of a generic Scope<KtElement>, then repeat recursively for all elements in the tree
👍 2
because that gives users the power to receive rich scopes that they can further expand to solve the problems as they dig down the tree
There is an equivalence in what you are doing and the other side
a
It may make sense to reorganize some of this then, if we'll be reusing custom scopes throughout
r
Scope is
KtElment -> Rendering
Element Scope is
Rendering -> KtElement
Where rendering is sources as Strings
there is a DSL in Element Scope that is the inverse of what you are doing
and as you improve the scopes in the quote that DSL can be improved to return most concrete scopes for specialized types
for example when you do :
Copy code
"fun ...".function
you should get a
FuncScope
instead of
Scope<KtNamedFunction>
same goes for all the rest in that DSL, as the quotes improve so should the counterpart to match the new created scopes that replace current generic representations
a
ohh okay, I see what's happening there now - the goal is to replace all that eventually
replace any Scope<KtElement> for a specialized Scope for that element that allows template destructuring
in that file
For example this one about KtParameter is outdated now
b
nice, for me that makes a lot of sense, and I'm actually doing exactly that to
KtLoopExpression
/
KtForExpression
, I'll send you the implementation later @amanda.hinchman-dominguez to see if I'm missing or misunderstanding something
👍 1
a
hahaha same
I think we can create sort of a "checklist" template in PRs for these kinds of tickets