Skip to content

Conversation

@jfeingold35
Copy link
Contributor

@jfeingold35 jfeingold35 commented Jul 5, 2022

This PR does the following:

  • Adds a new vertex property, InterfaceDefiningTypes, which captures the full defining type of each interface implemented by a class, and a case-safe equivalent for this property.
    These properties are populated during the execution of InheritanceEdgeBuilder.
  • Adds robust test coverage for the new and existing functionality of InheritanceEdgeBuilder.
  • Adds a case-safe equivalent for the existing property, ReturnType.
  • Adds a new case-safe traversal method, hasArrayContaining(), which returns vertices whose value of a specified property is an array containing a specified value.
  • Adds a new TraversalUtil method, traverseImplementationsOf(), which traverses every class that implements a given interface both directly and indirectly (i.e., extends a class that implements it, or implements an interface that extends it), along with robust test coverage for this new method.
  • Adds the Messaging.InboundEmailResult handleInboundEmail() method on Messaging.InboundEmailHandler implementations (both direct and indirect) as entrypoints for ApexFlsViolationRule.

Change to be added in supplemental PR:

  • Rename InheritanceEdgeBuilder to something like InheritanceInformationCreator, since it now does more than just building edges.

public static final String IDENTIFIER = "Identifier";
public static final String IMPLEMENTATION_OF = "ImplementationOf";
public static final String IMPLEMENTED_BY = "ImplementedBy";
public static final String INTERFACE_DEFINING_TYPES = "InterfaceDefiningTypes";
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New property added because the existing INTERFACE_NAMES property isn't guaranteed to contain the full defining types of interfaces, which was making queries very complicated.

Schema.NAME,
Schema.DEFINING_TYPE,
Schema.FULL_METHOD_NAME,
Schema.INTERFACE_DEFINING_TYPES,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Case-safe equivalent for new property.

Schema.INTERFACE_NAMES,
Schema.METHOD_NAME,
Schema.NAME,
Schema.RETURN_TYPE,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The lack of a case-safe return type was a problem.

}
}

public static GraphTraversal<Object, Object> hasArrayContaining(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the opposite of H.hasWithin(). Instead of checking whether a property's value is contained by the provided array, it checks whether a property represents an array containing the provided value.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be helpful to have this information as javadoc.

// It's possible for the implementedVertex to be null if the interface being
// implemented is declared in a file
// that wasn't scanned.
if (!implementedVerticesByName.isEmpty()) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switched to isEmpty check, since the map is always non-null.

@@ -1,7 +1,19 @@
package com.salesforce.graph.build;

import static org.hamcrest.Matchers.hasSize;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added aggressive test coverage for every scenario I could think of, since there was previously none.

__.where(
H.hasArrayContaining(
NodeType.USER_CLASS,
Schema.INTERFACE_DEFINING_TYPES,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new property makes this query significantly less complicated.

// subtypes. Do that with a union of these two subtraversals.
// Also, start with the hasLabel() call, because doing an initial filter along an indexed
// field saves us a ton of time.
GraphTraversal<Vertex, Vertex> traversal =
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This query is complicated, but I tried to document it as best I could. Please let me know if anything is unclear.

// Also, start with the hasLabel() call, because doing an initial filter along an indexed
// field saves us a ton of time.
GraphTraversal<Vertex, Vertex> traversal =
g.V().hasLabel(NodeType.USER_CLASS, NodeType.USER_INTERFACE)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This hasLabel call isn't technically necessary, but adding it improved the performance of the query substantially.

+ " }\n"
+ "}\n";

private String[] interfaceTestSourceCodes = {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added aggressive test coverage for the new traversal, with every test case I could think of.

// Filter the results by return type and arity to limit the possibility of
// getting unnecessary results.
.where(H.has(NodeType.METHOD, Schema.RETURN_TYPE, INBOUND_EMAIL_RESULT))
.has(Schema.ARITY, 2));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At this time, we're only checking the arity, instead of checking the types of arguments. We could add that in the future, but that feels like an excessive level of complication unless we know we'll need it. (He said, having already overcomplicated the PR...)

Copy link
Contributor

@rmohan20 rmohan20 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!

@jfeingold35 jfeingold35 merged commit 36f2c23 into dev-3 Jul 6, 2022
@jfeingold35 jfeingold35 deleted the d/W-10459675-4 branch September 14, 2022 18:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants