-
Notifications
You must be signed in to change notification settings - Fork 634
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[DYN-1682]: Improve node warning, autocomplete and Node2Code behavior with class name conflicts #10558
Conversation
@aparajit-pratap it looks good except for one question regarding tests. |
LGTM |
There is a regression I found in node to code (for which there was no test) so I'm continuing on this to fix that. |
foreach (var hierarchy in classHierarchies) | ||
{ | ||
// If A derives from B, which derives from C, the hierarchy for A | ||
// is listed in that order: [A, B, C], so we start searching in reverse order. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
src/Engine/ProtoCore/ClassTable.cs
Outdated
@@ -393,7 +393,7 @@ public class ClassTable | |||
//Symbol table to manage symbols with namespace | |||
private Namespace.SymbolTable symbolTable = new Namespace.SymbolTable(); | |||
|
|||
private List<ClassNode> GetClassHierarchy(ClassNode node) | |||
public List<ClassNode> GetClassHierarchy(ClassNode node) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does internal
work here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, since this method is defined in ProtoCore
but now being used in DynamoCore
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand this is being used by dynamo core - we also can use the internalsVisibleTo attribute to expose internal members to other assemblies which we own.
We should develop this principal further, but a few points.
- ProtoCore.dll is currently shipped as a part of the DynamoCore nuget package. To me looking at this package, as an external developer I see this as part of the API.
- A public method in this assembly which is shipped as part of a nuget package, will end up needing to be maintained.
Is this method something that should be used externally by integrators? Is there a compelling reason to make it part of the API? An interesting use case? A workflow that cannot be implemented without it?
If not, then what is the benefit?
If yes, then great, let's add documentation to it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have we made a decision on going forward with reducing the API surface of DynamoCore, DynamoCoreWpf etc. by continuing to expose them as our public API or are we deciding on keeping them as-is and making them internal and having a separate API layer for public consumption (based on your RFC)?
Whatever is the strategy, I think then we should come up with certain coding guidelines before we continue to make PR's. Going by the RFC again, it sounds like none of ProtoCore should be part of the API and we should surface just the AST's publicly. I'll make this method internal as well for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, we have made no decision -very much welcome those discussions - there are many options.
Thanks for addressing this, I don't think we can stop all work before we entirely decide this - but what I am suggesting is that we proceed conservatively until we do so.
I think it's likely we will find that some users are already using ProtoCore, and other binaries we didn't consider fully as APIs.
For example, the Civil3d integration has very specific interactions with callsites and trace, I am not 100% what APIs that team uses to control and redirect trace but I guess it is in protocore.
shortName = shortNames[new ProtoCore.Namespace.Symbol(qualifiedName)]; | ||
if (hierarchy[i] == qualifiedClassNode) | ||
{ | ||
shortName = shortNames[new Symbol(hierarchy[0].Name)]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just double checking - this should always be 0
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we want the most derived class in that list.
Purpose
This attempts to fix an inconsistent behavior with multiple definition warnings being shown when making certain function calls in CBN's vs. executing the nodes without errors.
In the example below, there are 2
List
classes, one, the built-in type and the other from a package (Orchid). Autocomplete displays both theList
classes, the second one prefixed with a namespace (Orchid) to distinguish it uniquely from the first. Autocomplete indicates that the firstList
type can be used as-is. Even then the node would show multiple definition warnings indicating it cannot resolve whichList
class to use. However, at runtime, this does not pose an issue and the node executes without any errors. This clearly inconsistent behavior is fixed here.The new behavior shows no multiple definition warnings when the CBN is initially created and is consistent both with the autocomplete prompts and the successful execution.
In addition to the above, few other existing bugs have been fixed in CBN autocomplete and in Node to Code. These are better explained with an example of List, DSCore.List, and Orchid.Core.List, where
DSCore.List
is hidden from the library andList
is a class in the global namespace that derives fromDSCore.List
.Orchid.Core.List
is an external class from a package.Some notes to keep in mind:
ShortestQualifiedNameReplacer
class that basically rewrites a collection of classes, all having the same name, but with different namespaces. This component ensures that the full names of these classes are automatically shortened (to make CBN code less verbose) so that they can still be resolved uniquely. For example, in this case,Orchid.Core.List
, can be renamed toOrchid.List
, by dropping theCore
, from its full namespace as DesignScript (in its implementation of Dynamo only) can still recognize it uniquely, separate from the other two.IsVisibleInLibrary(false)
attribute) do not show in the library and for consistency, we should not make them appear in code in CBNs either. However, a hidden class can have explicitly visible methods and properties (if overridden withIsVisibleInLibrary(true)
attribute), which will show up as nodes in the library. Only if such a class is inherited by a subclass, will its methods be displayed in autocomplete in CBN under the derived class. An example of such a class isDSCore.List
, where its methods are visible as nodes in the library and they appear underList
in CBN autocomplete. Hidden classes if used in CBN (even if not discovered by autocomplete) will still autocomplete to show its members.ElementResolver
maintains a map of short names vs. fully qualified names, based on their use in CBNs. The purpose of this map is such that if a new library with a conflicting classname is imported into an existing graph, CBN code continues to work and does not break even in the presence of a new conflict that is introduced at a later time. These conflicts if left to be resolved by the compiler could give new results causing existing graphs to break. In such cases, we lean on the ER to give us the exact classname that was resolved earlier.1. Autocomplete behavior and fixes
L
,i
,s
..., autocomplete begins to filter all the classes with the nameList
and only showsList
andOrchid.List
as it hides the hiddenDSCore.List
classList
, all methods and properties onList
and its base class (DSCore.List
) are displayedDSCore.List
- (1) no autocomplete onDSCore
namespace is expected and (2) code completion onDSCore.List
, will display method list only on that base class (not on the derivedList
class)2. Node warning fixes
List
,DSCore.List
orOrchid.Core.List
must not throw amultiple definition warning
at compile time as all of them are expected to resolve uniquely (both as nodes as well as in CBN code).Before:
After:
3. Node To Code behavior and fixes
List
nodes should generateList._MethodName_
andList._PropertyName(obj)_
in CBNDSCore.List
nodes should also generate theList._MethodName_
as above (sinceDSCore.List
is hidden and is a base class ofList
)Orchid.Core.List
node should generate CBN with the shortest unique name when compared with all other classes with the nameList
, which in this case isOrchid.List._MethodName_
.Before:
After:
4. Prefixing classes with full namespaces without assistance from autocomplete
ElementResolver
. For e.g., if a user types the full name:Orchid.Core.List
, even thoughOrchid.List
would suffice,Orchid.Core.List
would start appearing in autocomplete and in N2C code.ElementResolver
as if it is, the hidden class will start to unexpectedly appear in CBN autocomplete and N2C behavior, which will be confusing to the end-user. For example, ifDSCore.List
is typed into a CBN, it will not be added to theElementResolver
so that it does not appear in any CBN autocompletion lists or N2C code generated subsequently.Note that there is a proposal to display the contents of the ER map in the UI, so that it is not a Blackbox and so that users can understand why in their graph certain namespaces in CBNs are working and why others are not.
Declarations
Check these if you believe they are true
*.resx
filesReviewers
@DynamoDS/dynamo
FYIs
@Amoursol