Skip to content

Commit

Permalink
Refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
ccal2 committed Jul 30, 2023
1 parent d1bea41 commit e5fd504
Show file tree
Hide file tree
Showing 12 changed files with 104 additions and 155 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -76,26 +76,11 @@ class ContextTreeGeneratorVisitor: SyntaxVisitor {
}

override func visit(_ node: VariableDeclSyntax) -> SyntaxVisitorContinueKind {
let variableDeclContext = VariableDeclarationContext(parent: currentContext, isStatic: isStatic(modifiers: node.modifiers))
currentContext = variableDeclContext

return .visitChildren
}

override func visitPost(_ node: VariableDeclSyntax) {
guard let parentContext = currentContext.parent else {
fatalError("currentContext.parent can't be nil after visiting something because there will always be the global context")
if let identifier = node.bindings.first?.pattern.as(IdentifierPatternSyntax.self)?.identifier.text {
_ = VariableDeclarationContext(parent: currentContext, identifier: identifier, isStatic: isStatic(modifiers: node.modifiers))
}
currentContext = parentContext
}

override func visit(_ node: IdentifierPatternSyntax) -> SyntaxVisitorContinueKind {
if let variableDeclContext = currentContext as? VariableDeclarationContext {
variableDeclContext.identifier = node.identifier.text
}
// else...

return .skipChildren
return .visitChildren
}

override func visit(_ node: FunctionDeclSyntax) -> SyntaxVisitorContinueKind {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ class TypeContext: Context {
let kind: TypeKind

private(set) lazy var fullIdentifier: String = {
// Since allPossibleIdentifiers starts with one element, it will never be empty
allPossibleIdentifiers.last!
allPossibleIdentifiers.last ?? identifier
}()

private(set) lazy var allPossibleIdentifiers: [String] = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ class VariableDeclarationContext: Context {

// MARK: - Properties

var identifier: String?
let identifier: String
let isStatic: Bool

// MARK: - Initializers

init(parent: Context, isStatic: Bool) {
init(parent: Context, identifier: String, isStatic: Bool) {
self.identifier = identifier
self.isStatic = isStatic
super.init(parent: parent)
}
Expand Down
4 changes: 2 additions & 2 deletions Swift-Metrics-Collector/SMCKit/SMCKit/ElementsTree.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class ElementsTree {
var superTypeNode: TypeNode? = nil
if context.firstInheritedType != nil {
guard let superTypeNodeIndex = allTypes.firstIndex(where: { typeNode in
typeNode.context.isSuperType(of: context)
typeNode.isSuperType(of: context)
}) else {
contextsWaitingForSuperType.append(context)
return
Expand All @@ -89,7 +89,7 @@ class ElementsTree {

var index = 0
while index < contextsWaitingForSuperType.count {
guard typeNode.context.isSuperType(of: contextsWaitingForSuperType[index]) else {
guard typeNode.isSuperType(of: contextsWaitingForSuperType[index]) else {
index += 1
continue
}
Expand Down
31 changes: 12 additions & 19 deletions Swift-Metrics-Collector/SMCKit/SMCKit/Nodes/ContainerNode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,24 @@
// Created by Carolina Lopes on 12/04/23.
//

protocol ContainerNodeObject: NodeObject {
var variables: Set<VariableNode> { get }
var methods: Set<MethodNode> { get }
}

class ContainerNode<ContextType: Context>: Node<ContextType>, ContainerNodeObject {
class ContainerNode: Node {

private(set) lazy var variables: Set<VariableNode> = {
var variables: Set<VariableNode> = []
// MARK: - Properties

for context in context.variableDeclarations {
variables.insert(VariableNode(parent: self, context: context))
}
private(set) var variables: Set<VariableNode> = []
private(set) var methods: Set<MethodNode> = []

return variables
}()
// MARK: - Initializers

private(set) lazy var methods: Set<MethodNode> = {
var methods: Set<MethodNode> = []
init(parent: Node?, context: Context) {
super.init(parent: parent)

for context in context.variableDeclarations {
self.variables.insert(VariableNode(parent: self, context: context))
}
for context in context.methods {
methods.insert(MethodNode(parent: self, context: context))
self.methods.insert(MethodNode(parent: self, context: context))
}

return methods
}()
}

}
62 changes: 23 additions & 39 deletions Swift-Metrics-Collector/SMCKit/SMCKit/Nodes/MethodNode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,51 +5,23 @@
// Created by Carolina Lopes on 10/04/23.
//

class MethodNode: ContainerNode<MethodContext> {
class MethodNode: ContainerNode {

// MARK: - Properties

var methodCalls: Set<String> {
context.methodCalls
}

private(set) lazy var identifier: String = {
context.identifier
}()

private(set) lazy var isStatic: Bool = {
context.isStatic
}()

private(set) lazy var parameters: Set<MethodParameterNode> = {
var parameters: Set<MethodParameterNode> = []

for context in context.parameters {
parameters.insert(MethodParameterNode(parent: self, context: context))
}

return parameters
}()

private(set) lazy var returnTypeIdentifier: String? = {
context.returnTypeIdentifier
}()

private(set) lazy var variableAccesses: Set<VariableAccessNode> = {
var variableAccesses: Set<VariableAccessNode> = []

for accessContext in context.variableAccesses {
variableAccesses.insert(VariableAccessNode(parent: self, context: accessContext))
}
let methodCalls: Set<String>
let identifier: String
let isStatic: Bool
let returnTypeIdentifier: String?

return variableAccesses
}()
private(set) var parameters: Set<MethodParameterNode> = []
private(set) var variableAccesses: Set<VariableAccessNode> = []

// If an instance variable is accessed without self and later on a local variable is declared with the same name, that access will be ignored!
// [Limitation]: If an instance variable is accessed without self and later on a local variable is declared with the same name, that access will be ignored!
// To fix this, we'd need to save the indexes of the declaration and the access and use that when identifying whether an access is related to an instance variable or not
private(set) lazy var accessedInstanceVariables: Set<VariableNode> = {
// localVariables will store all variables declared inside this method or any other method that includes it (until the type declaration is reached)
// e.g.: class A { func fA() { class B { func fB() { func gB() {} } } } } | object is method f: all variables declared in methods f and g
// localVariables will store all variables declared inside this method or any other method that it includes (until the type declaration is reached)
// e.g.: class A { func fA() { class B { func fB() { func gB() {} } } } } | object is method fB: all variables declared in methods fB and gB
var localVariables = variables

var node = parent
Expand Down Expand Up @@ -89,8 +61,20 @@ class MethodNode: ContainerNode<MethodContext> {

// MARK: - Initializers

init(parent: (any ContainerNodeObject)?, context: MethodContext) {
init(parent: Node?, context: MethodContext) {
self.methodCalls = context.methodCalls
self.identifier = context.identifier
self.isStatic = context.isStatic
self.returnTypeIdentifier = context.returnTypeIdentifier

super.init(parent: parent, context: context)

for context in context.parameters {
self.parameters.insert(MethodParameterNode(parent: self, context: context))
}
for accessContext in context.variableAccesses {
self.variableAccesses.insert(VariableAccessNode(parent: self, context: accessContext))
}
}

// MARK: - Methods
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,33 @@
// Created by Carolina Lopes on 10/04/23.
//

class MethodParameterNode: Node<MethodParameterContext> {
class MethodParameterNode: Node {

// MARK: - Properties

private(set) lazy var label: String? = {
context.firstName
}()
let label: String?
let identifier: String
let typeIdentifier: String

private(set) lazy var identifier: String = {
if let secondName = context.secondName {
return secondName
}

guard let firstName = context.firstName else {
fatalError("Missing identifier in parameter")
}

return firstName
}()
// MARK: - Initializers

private(set) lazy var typeIdentifier: String = {
init(parent: MethodNode, context: MethodParameterContext) {
guard let type = context.typeIdentifier else {
fatalError("Missing type identifier in parameter")
}

return type
}()

// MARK: - Initializers
self.label = context.firstName
if let secondName = context.secondName {
self.identifier = secondName
} else {
guard let firstName = context.firstName else {
fatalError("Missing identifier in parameter")
}
self.identifier = firstName
}
self.typeIdentifier = type

init(parent: MethodNode, context: MethodParameterContext) {
super.init(parent: parent, context: context)
super.init(parent: parent)
}

// MARK: - Methods
Expand Down
22 changes: 7 additions & 15 deletions Swift-Metrics-Collector/SMCKit/SMCKit/Nodes/Node.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,26 @@
// Created by Carolina Lopes on 19/04/23.
//

protocol NodeObject: AnyObject {
associatedtype ContextType: Context

var context: ContextType { get }
var parent: (any NodeObject)? { get }
}

class Node<ContextType: Context>: NodeObject {
typealias ContextType = ContextType
class Node {

// MARK: - Properties

let context: ContextType
private(set) weak var parent: (any NodeObject)?
private(set) weak var parent: Node?

private let uuid = UUID()

// MARK: - Initializers

init(parent: (any NodeObject)?, context: ContextType) {
init(parent: Node?) {
self.parent = parent
self.context = context
}


// MARK: - Hashable

// Declared here so it can be overridden by subclasses
func hash(into hasher: inout Hasher) {
hasher.combine(context)
hasher.combine(uuid)
}

}
Expand All @@ -42,7 +34,7 @@ class Node<ContextType: Context>: NodeObject {
extension Node: Hashable {

static func == (lhs: Node, rhs: Node) -> Bool {
lhs.context == rhs.context
lhs.uuid == rhs.uuid
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@
// Created by Carolina Lopes on 03/05/23.
//

class TypeExtensionNode: ContainerNode<TypeExtensionContext> {
class TypeExtensionNode: ContainerNode {

// MARK: - Properties

private(set) lazy var identifier: String = {
context.identifier
}()
let identifier: String

// MARK: - Initializers

init(parent: TypeNode, context: TypeExtensionContext) {
self.identifier = context.identifier

super.init(parent: parent, context: context)

parent.extensions.insert(self)
Expand Down
26 changes: 17 additions & 9 deletions Swift-Metrics-Collector/SMCKit/SMCKit/Nodes/TypeNode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,18 @@
// Created by Carolina Lopes on 20/03/23.
//

class TypeNode: ContainerNode<TypeContext> {
class TypeNode: ContainerNode {

// MARK: - Properties

let kind: TypeKind
let identifier: String
let allPossibleIdentifiers: [String]

var extensions: Set<TypeExtensionNode> = []

private(set) var children: Set<TypeNode> = []

private(set) lazy var kind: TypeKind = {
context.kind
}()

private(set) lazy var identifier: String = {
context.fullIdentifier
}()

// MARK: Computed properties

var variablesIncludingExtensions: Set<VariableNode> {
Expand Down Expand Up @@ -84,13 +80,25 @@ class TypeNode: ContainerNode<TypeContext> {
// MARK: - Initializers

init(parent: TypeNode?, context: TypeContext) {
self.kind = context.kind
self.identifier = context.fullIdentifier
self.allPossibleIdentifiers = context.allPossibleIdentifiers

super.init(parent: parent, context: context)

parent?.children.insert(self)
}

// MARK: - Methods

func isSuperType(of context: TypeContext) -> Bool {
guard let firstInheritedType = context.firstInheritedType else {
return false
}

return allPossibleIdentifiers.contains(firstInheritedType)
}

func printableDescription(indentationLevel: Int = 0) -> String {
let prefix = Array(repeating: "\t", count: indentationLevel).joined()

Expand Down
Loading

0 comments on commit e5fd504

Please sign in to comment.