From 363eb397e78e07532b2424158afeb1b187650b4d Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 21 Sep 2026 13:57:01 +0200 Subject: [PATCH 1/2] Type inference: Generalize interface in preparation for Unified --- .../internal/typeinference/TypeInference.qll | 4 +- .../typeinference/internal/TypeInference.qll | 130 +++++++++++++++--- 2 files changed, 111 insertions(+), 23 deletions(-) diff --git a/rust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qll b/rust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qll index d591c947e124..1a6728e27301 100644 --- a/rust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qll +++ b/rust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qll @@ -2917,7 +2917,9 @@ private module Input3 implements InputSig3 { ) } - class Closure extends Expr, Callable instanceof Rust::ClosureExpr { } + class Closure extends Expr, Callable instanceof Rust::ClosureExpr { + Expr getDefiningExpr() { result = this } + } class ClosureParameterPseudoType extends T::ClosureParameterPseudoType { Parameter getParameter() { result = this.getParam() } diff --git a/shared/typeinference/codeql/typeinference/internal/TypeInference.qll b/shared/typeinference/codeql/typeinference/internal/TypeInference.qll index 399e5d818c87..f7fa0592df2f 100644 --- a/shared/typeinference/codeql/typeinference/internal/TypeInference.qll +++ b/shared/typeinference/codeql/typeinference/internal/TypeInference.qll @@ -79,7 +79,14 @@ signature module InputSig1 { * For example `int` or ``IEnumerable`1``. */ class Type { - /** Gets a type parameter of this type, if any. */ + /** Gets the `i`th positional type parameter of this type, if any. */ + TypeParameter getPositionalTypeParameter(int i); + + /** + * Gets a type parameter of this type, if any. + * + * This may include non-positional type parameters as well. + */ TypeParameter getATypeParameter(); /** Gets a textual representation of this type. */ @@ -2041,7 +2048,7 @@ module Make1 Input1> { * item in Rust. */ class Variable { - /** Gets the AST node that defines this variable. */ + /** Gets the AST node that defines this variable, if any. */ AstNode getDefiningNode(); /** Gets an access to this variable. */ @@ -2055,7 +2062,7 @@ module Make1 Input1> { } /** A declaration. */ - class Declaration extends AstNode { + class Declaration { /** * Gets the type mention of the entity that contains this declaration, if any. * @@ -2088,6 +2095,12 @@ module Make1 Input1> { * a function. */ TypeMention getType(); + + /** Gets a textual representation of this declaration. */ + string toString(); + + /** Gets the location of this declaration. */ + Location getLocation(); } /** @@ -2167,6 +2180,12 @@ module Make1 Input1> { /** A parameter. */ class Parameter extends VariableDeclaration; + /** + * Holds if `p` is an implicit parameter declaration corresponding + * to variable `v`. + */ + default predicate implicitParameterDecl(Parameter p, Variable v) { none() } + /** A callable. This may include for example variant constructors. */ class Callable extends Declaration { /** @@ -2368,7 +2387,10 @@ module Make1 Input1> { } /** A closure/lambda expression. */ - class Closure extends Callable, Expr; + class Closure extends Callable { + /** Gets the expression that defines this closure (typically the entity itself). */ + Expr getDefiningExpr(); + } /** * A special pseudo type representing a particular closure parameter without @@ -2484,12 +2506,14 @@ module Make1 Input1> { module Make3 { private import Input3 - private predicate closureStep(AstNode pattern, TypePath prefix1, Closure c, TypePath prefix2) { - exists(Parameter p | + pragma[nomagic] + private predicate closureStep(AstNode pattern, TypePath prefix1, Expr c, TypePath prefix2) { + exists(Closure c0, Parameter p | pattern = p.getPattern() and - p = c.getParameter(_) and + p = c0.getParameter(_) and prefix1.isEmpty() and - prefix2 = getClosureParameterTypePath(p) + prefix2 = getClosureParameterTypePath(p) and + c = c0.getDefiningExpr() ) } @@ -2513,10 +2537,16 @@ module Make1 Input1> { tm = decl.getType() and n = decl.getPattern() ) + or + exists(Parameter p, Variable v | + implicitParameterDecl(p, v) and + result = p.getType().getTypeAt(path) and + n = v.getAnAccess() + ) ) or exists(Closure c, TypePath suffix | - n = c and + n = c.getDefiningExpr() and result = getCallableReturnType(c, suffix) and path = getClosureReturnTypePath(c).append(suffix) ) @@ -2615,8 +2645,11 @@ module Make1 Input1> { or result = inferLogicalOperationType(n, path) or - result = getClosureType(n) and - path.isEmpty() + exists(Closure c | + n = c.getDefiningExpr() and + result = getClosureType(c) and + path.isEmpty() + ) or infersCertainTypeAt(n, path, result.getATypeParameter()) ) and @@ -2709,9 +2742,9 @@ module Make1 Input1> { or exists(Closure c | n1 = c.getBody() and - n2 = c and + n2 = c.getDefiningExpr() and prefix1.isEmpty() and - prefix2 = getClosureReturnTypePath(n2) + prefix2 = getClosureReturnTypePath(c) ) } @@ -2725,7 +2758,10 @@ module Make1 Input1> { or closureStep(n2, prefix2, n, prefix1) and // prevent closure parameter pseudo types from escaping the closure - not result.(ClosureParameterPseudoType).getParameter() = n.(Closure).getParameter(_) + not exists(Closure c | + n = c.getDefiningExpr() and + result.(ClosureParameterPseudoType).getParameter() = c.getParameter(_) + ) ) } @@ -3076,7 +3112,7 @@ module Make1 Input1> { } pragma[nomagic] - private predicate hasUnknownTypeAt(AstNode n, TypePath path) { + predicate hasUnknownTypeAt(AstNode n, TypePath path) { inferType(n, path) instanceof UnknownType } @@ -3209,8 +3245,8 @@ module Make1 Input1> { result.(ClosureParameterPseudoType).getParameter() = p or // step 3 - hasClosureParameterPseudoType(c, path, p) and - n = c and + hasClosureParameterPseudoType(n, path, p) and + n = c.getDefiningExpr() and result instanceof UnknownType ) or @@ -3227,23 +3263,64 @@ module Make1 Input1> { or // The `step X` comments below refer to the steps for 'Case A' in the // QL doc for `ClosureParameterPseudoType`. - exists(Closure c, Parameter p | + exists(Closure c, Parameter p, Expr def | p = c.getParameter(_) and - not exists(p.getType()) + not exists(p.getType()) and + def = c.getDefiningExpr() | // step 1 - n = c and + n = def and path = getClosureParameterTypePath(p) and result instanceof UnknownType or // step 3 n = p.getPattern() and - result = inferType(c, getClosureParameterTypePath(p).appendInverse(path)) and + result = inferType(def, getClosureParameterTypePath(p).appendInverse(path)) and not (path.isEmpty() and result instanceof UnknownType) ) } } + /** + * Holds if `n` has unknown type at at `prefix`, but is still able to + * infer a known type at `suffix` for the `i`th type parameter of whatever + * the unknown type is. + * + * For example, in + * + * ```rust + * let mut x: Unresolvable = ...; + * + * x = resolvable(...); + * ``` + * + * even though the root type is unresolvable at the declaration, we are still + * able to infer that the first type argument is `i32`. We can then combine this + * information with later inferred type information. + */ + pragma[nomagic] + private predicate infersUnknownTypeArg( + AstNode n, TypePath prefix, int i, TypePath suffix, Type t + ) { + exists(TypeParameter tp, TypePath suffix0 | + ContextualTyping::hasUnknownTypeAt(n, prefix) and + suffix0.isCons(tp, suffix) and + tp = any(UnknownType ut).getPositionalTypeParameter(i) and + t = inferType(n, prefix.appendInverse(suffix0)) and + not t instanceof UnknownType + ) + } + + pragma[nomagic] + private predicate infersKnownAndUnknownType(AstNode n, TypePath path, int i, TypeParameter tp) { + ContextualTyping::hasUnknownTypeAt(n, path) and + exists(Type t | + t = inferType(n, path) and + not t instanceof UnknownType and + tp = t.getPositionalTypeParameter(i) + ) + } + /** * Gets an inferred candidate type of `n` at `path`. * @@ -3275,6 +3352,12 @@ module Make1 Input1> { result instanceof UnknownType or result = ContextualTyping::inferTypeContextual(n, path) + or + exists(TypePath prefix, int i, TypePath suffix, TypeParameter tp | + infersUnknownTypeArg(n, prefix, i, suffix, result) and + infersKnownAndUnknownType(n, prefix, i, tp) and + path = prefix.append(TypePath::cons(tp, suffix)) + ) } /** @@ -3298,7 +3381,10 @@ module Make1 Input1> { result instanceof ClosureParameterPseudoType ) and // prevent closure parameter pseudo types from escaping from the closure - not result.(ClosureParameterPseudoType).getParameter() = n.(Closure).getParameter(_) + not exists(Closure c | + n = c.getDefiningExpr() and + result.(ClosureParameterPseudoType).getParameter() = c.getParameter(_) + ) or // If `n` has an explicitly unknown type at `prefix` and at the same time a certain // type at `prefix.suffix`, then extend the unknown type information to any path From aaad4c2b2bfa02a2ae6ff2a87299bc80da290c0c Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 22 Sep 2026 15:34:37 +0200 Subject: [PATCH 2/2] Unified: Type inference first version --- .../TypeInferenceConsistency.ql | 8 + .../codeql/unified/internal/ExprPositions.qll | 4 + .../lib/codeql/unified/internal/FacadeAst.qll | 10 + .../unified/internal/LocalNameBinding.qll | 60 +- .../unified/internal/StaticNameBinding.qll | 2 + .../unified/internal/dataflow/CallGraph.qll | 13 +- .../unified/internal/typeinference/Type.qll | 219 ++ .../typeinference/TypeAbstraction.qll | 19 + .../internal/typeinference/TypeInference.qll | 742 +++++ .../TypeInferenceConsistency.qll | 19 + .../typeinference/TypeInferencePlugin.qll | 152 + .../TypeInferencePluginSwift.qll | 171 ++ .../internal/typeinference/TypeMention.qll | 159 + unified/ql/lib/qlpack.yml | 1 + .../test/ExternalLocationPostProcessing.ql | 9 + unified/ql/lib/utils/test/TestUtils.qll | 46 + .../ql/test/library-tests/BasicTest/test.ql | 8 +- .../TypeInferenceConsistency.expected | 3 + .../test/library-tests/dataflow/calls.swift | 8 +- .../test/library-tests/dataflow/test.expected | 16 + .../CONSISTENCY/CfgConsistency.expected | 7 + .../library-tests/type-inference/basics.swift | 63 + .../type-inference/classes.swift | 205 ++ .../type-inference/closures.swift | 49 + .../type-inference/context.swift | 7 + .../library-tests/type-inference/fields.swift | 43 + .../type-inference/generics.swift | 274 ++ .../type-inference/key_paths.swift | 210 ++ .../library-tests/type-inference/lub.swift | 15 + .../type-inference/overload_resolution.swift | 445 +++ .../type-inference/pattern_matching.swift | 33 + .../type-inference/protocols.swift | 104 + .../type-inference/type-inference.expected | 2555 +++++++++++++++++ .../type-inference/type-inference.ql | 48 + .../type-inference/type-inference.qlref | 2 + .../type-inference/type_constraints.swift | 264 ++ unified/tools/builtins/types.swift | 91 +- 37 files changed, 6009 insertions(+), 75 deletions(-) create mode 100644 unified/ql/consistency-queries/TypeInferenceConsistency.ql create mode 100644 unified/ql/lib/codeql/unified/internal/typeinference/Type.qll create mode 100644 unified/ql/lib/codeql/unified/internal/typeinference/TypeAbstraction.qll create mode 100644 unified/ql/lib/codeql/unified/internal/typeinference/TypeInference.qll create mode 100644 unified/ql/lib/codeql/unified/internal/typeinference/TypeInferenceConsistency.qll create mode 100644 unified/ql/lib/codeql/unified/internal/typeinference/TypeInferencePlugin.qll create mode 100644 unified/ql/lib/codeql/unified/internal/typeinference/TypeInferencePluginSwift.qll create mode 100644 unified/ql/lib/codeql/unified/internal/typeinference/TypeMention.qll create mode 100644 unified/ql/lib/utils/test/ExternalLocationPostProcessing.ql create mode 100644 unified/ql/test/library-tests/controlflow/CONSISTENCY/TypeInferenceConsistency.expected create mode 100644 unified/ql/test/library-tests/type-inference/CONSISTENCY/CfgConsistency.expected create mode 100644 unified/ql/test/library-tests/type-inference/basics.swift create mode 100644 unified/ql/test/library-tests/type-inference/classes.swift create mode 100644 unified/ql/test/library-tests/type-inference/closures.swift create mode 100644 unified/ql/test/library-tests/type-inference/context.swift create mode 100644 unified/ql/test/library-tests/type-inference/fields.swift create mode 100644 unified/ql/test/library-tests/type-inference/generics.swift create mode 100644 unified/ql/test/library-tests/type-inference/key_paths.swift create mode 100644 unified/ql/test/library-tests/type-inference/lub.swift create mode 100644 unified/ql/test/library-tests/type-inference/overload_resolution.swift create mode 100644 unified/ql/test/library-tests/type-inference/pattern_matching.swift create mode 100644 unified/ql/test/library-tests/type-inference/protocols.swift create mode 100644 unified/ql/test/library-tests/type-inference/type-inference.expected create mode 100644 unified/ql/test/library-tests/type-inference/type-inference.ql create mode 100644 unified/ql/test/library-tests/type-inference/type-inference.qlref create mode 100644 unified/ql/test/library-tests/type-inference/type_constraints.swift diff --git a/unified/ql/consistency-queries/TypeInferenceConsistency.ql b/unified/ql/consistency-queries/TypeInferenceConsistency.ql new file mode 100644 index 000000000000..8e5c85b8be6e --- /dev/null +++ b/unified/ql/consistency-queries/TypeInferenceConsistency.ql @@ -0,0 +1,8 @@ +/** + * @name Type inference inconsistencies + * @description Lists the type inference inconsistencies in the database. This query is intended for internal use. + * @kind table + * @id unified/diagnostics/type-inference-consistency + */ + +import codeql.unified.internal.typeinference.TypeInferenceConsistency diff --git a/unified/ql/lib/codeql/unified/internal/ExprPositions.qll b/unified/ql/lib/codeql/unified/internal/ExprPositions.qll index 2e64053642eb..7db20df2038a 100644 --- a/unified/ql/lib/codeql/unified/internal/ExprPositions.qll +++ b/unified/ql/lib/codeql/unified/internal/ExprPositions.qll @@ -27,6 +27,10 @@ predicate isInTypeContext(Expr expr) { or expr = any(AssociatedTypeDeclaration n).getBound() or + expr = any(ClassLikeDeclaration c).getExtensionTarget() + or + expr = any(GenericTypeExpr gte).getATypeArgument() + or expr.getParent() instanceof TypeConstraint or isInTypeContext(expr.getEnclosingExpr()) diff --git a/unified/ql/lib/codeql/unified/internal/FacadeAst.qll b/unified/ql/lib/codeql/unified/internal/FacadeAst.qll index 31b3ec3d950d..1954ed53072f 100644 --- a/unified/ql/lib/codeql/unified/internal/FacadeAst.qll +++ b/unified/ql/lib/codeql/unified/internal/FacadeAst.qll @@ -209,6 +209,11 @@ module Unified { } } + class TupleExpr extends G::TupleExpr { + /** Gets the number of elements in this tuple expression. */ + int getNumberOfElements() { result = count(this.getAnElement()) } + } + class TypeAliasDeclaration extends G::TypeAliasDeclaration { /** Gets the name of this type alias. */ string getName() { result = this.getNameNode().getValue() } @@ -261,4 +266,9 @@ module Unified { /** Gets the number of arguments passed to this call, not counting implicit arguments like receiver. */ int getNumberOfArguments() { result = count(this.getAnArgument()) } } + + class FunctionExpr extends G::FunctionExpr { + /** Gets the number of parameters of this function. */ + int getNumberOfParameters() { result = count(this.getAParameter()) } + } } diff --git a/unified/ql/lib/codeql/unified/internal/LocalNameBinding.qll b/unified/ql/lib/codeql/unified/internal/LocalNameBinding.qll index 405455473d23..ff06b1896cdd 100644 --- a/unified/ql/lib/codeql/unified/internal/LocalNameBinding.qll +++ b/unified/ql/lib/codeql/unified/internal/LocalNameBinding.qll @@ -395,9 +395,26 @@ module Public { LocalName getLocalName() { result = this.(LocalNameBindingOutput::LocalAccess).getLocal() } } + final class LocalVariable = LocalVariableImpl; + /** A representative for a lexically scoped local variable. */ - class LocalVariable extends LocalName { - LocalVariable() { + abstract private class LocalVariableImpl extends LocalName { + /** Gets the callable containing the declaration of this local variable. */ + abstract Callable getDeclaringCallable(); + + /** Holds if this local variable is captured, that is, it is accessed from another callable than the one declaring it. */ + predicate isCaptured() { + this.getAnAccess().getEnclosingCallable() != this.getDeclaringCallable() + } + + /** + * Holds if this local variable represents an implicit receiver parameter of the given callable. + */ + abstract predicate isImplicitReceiverParameter(Callable c); + } + + private class ExplicitLocalVariable extends LocalVariableImpl { + ExplicitLocalVariable() { exists(AstNode decl | decl = this.getABinding().getDeclaration() and not isInstanceMember(decl) and @@ -411,29 +428,34 @@ module Public { decl instanceof CatchClause or decl instanceof SwitchCase ) - or + } + + override Callable getDeclaringCallable() { result = this.getABinding().getEnclosingCallable() } + + override predicate isImplicitReceiverParameter(Callable c) { none() } + } + + private class ImplicitLocalVariable extends LocalVariableImpl instanceof LocalNameBindingOutput::ImplicitLocal + { + AstNode scope; + string name; + + ImplicitLocalVariable() { // For implicitly-declared locals we can't expect to find a binding. Check 'implicitDeclInScope' directly. - exists(AstNode scope, string name | - this.(LocalNameBindingOutput::ImplicitLocal).hasNameAndScope(name, scope) and - LocalNameBindingInput::implicitDeclInScope(name, scope, true) - ) + super.hasNameAndScope(name, scope) and + LocalNameBindingInput::implicitDeclInScope(name, scope, true) } - /** Gets the callable containing the declaration of this local variable. */ - Callable getDeclaringCallable() { - result = this.getABinding().getEnclosingCallable() + override Callable getDeclaringCallable() { + result = scope or - exists(AstNode scope | scope = this.(LocalNameBindingOutput::ImplicitLocal).getScope() | - result = scope - or - not scope instanceof Callable and - result = scope.getEnclosingCallable() - ) + not scope instanceof Callable and + result = scope.getEnclosingCallable() } - /** Holds if this local variable is captured, that is, it is accessed from another callable than the one declaring it. */ - predicate isCaptured() { - this.getAnAccess().getEnclosingCallable() != this.getDeclaringCallable() + override predicate isImplicitReceiverParameter(Callable c) { + name = any(NameBindingPlugin p).getImplicitReceiverParameterName(scope) and + scope = c } } diff --git a/unified/ql/lib/codeql/unified/internal/StaticNameBinding.qll b/unified/ql/lib/codeql/unified/internal/StaticNameBinding.qll index 6736e52da0bf..578ed784cfdc 100644 --- a/unified/ql/lib/codeql/unified/internal/StaticNameBinding.qll +++ b/unified/ql/lib/codeql/unified/internal/StaticNameBinding.qll @@ -121,6 +121,8 @@ class NameBindingNode extends TNameBindingNode { Identifier getIdentifierFromRef(AstNode n) { result = n.(PotentialLocalNameAccess) or + result = n.(GenericTypeExpr).getBase() + or result = n.(MemberAccessExpr).getMemberNameNode() } diff --git a/unified/ql/lib/codeql/unified/internal/dataflow/CallGraph.qll b/unified/ql/lib/codeql/unified/internal/dataflow/CallGraph.qll index 226e2f15d93b..410d550db6ae 100644 --- a/unified/ql/lib/codeql/unified/internal/dataflow/CallGraph.qll +++ b/unified/ql/lib/codeql/unified/internal/dataflow/CallGraph.qll @@ -1,16 +1,7 @@ private import unified private import AllDataFlow -private import codeql.unified.internal.NameBinding as N - -private Callable getCallableFromNameBinding(NameBinding binding) { - binding = result.(FunctionDeclaration).getNameNode() -} +private import codeql.unified.internal.typeinference.TypeInference as T DataFlowCallable viableCallable(DataFlowCall c) { - exists(CallExpr call, Callable callable, NameBinding target | - c.asExplicitCall() = call and - target = N::getStaticBindingTarget(N::getIdentifierFromRef(call.getCallee())) and - callable = getCallableFromNameBinding(target) and - result.asSourceCallable() = callable - ) + result.asSourceCallable() = T::resolveCallTarget(c.asExplicitCall(), _) } diff --git a/unified/ql/lib/codeql/unified/internal/typeinference/Type.qll b/unified/ql/lib/codeql/unified/internal/typeinference/Type.qll new file mode 100644 index 000000000000..e6c84fa9ea9f --- /dev/null +++ b/unified/ql/lib/codeql/unified/internal/typeinference/Type.qll @@ -0,0 +1,219 @@ +/** Provides classes representing types without type arguments. */ + +import unified +private import unified as Unified +private import TypeInference +private import codeql.unified.internal.StaticNameBinding + +/** + * Holds if `a` is an associated type of `c`, in which case we model it + * as a type parameter. + * + * `inherited` indicates whether the associated type is declared in `c` + * or inherited from a base class. + */ +private predicate associatedTypeParameter( + ClassLikeDeclaration c, AssociatedTypeDeclaration a, boolean inherited +) { + a = c.getAMember() and + inherited = false + or + exists(string name | + associatedTypeParameterInherited(c, a, _, _, name) and + not c.getAMember().(TypeAliasDeclaration).getName() = name and + inherited = true + ) +} + +pragma[nomagic] +predicate associatedTypeParameterInherited( + ClassLikeDeclaration c, AssociatedTypeDeclaration a, ClassLikeDeclaration base, Expr baseRef, + string name +) { + associatedTypeParameter(base, a, _) and + baseRef = c.getABaseType().getType() and + base.getNameNode() = getStaticBindingTarget(baseRef) and + name = a.getName() +} + +cached +newtype TType = + TClassLikeDeclarationType(ClassLikeDeclaration c) { + CachedStage::ref() and + exists(c.getNameNode()) + } or + TClosureParameterPseudoType(Parameter p) { + exists(FunctionExpr fe | + p = fe.getAParameter() and + not exists(p.getType()) + ) + } or + TTypeParameterType(Unified::TypeParameter tp) or + TAssociatedTypeParameterType( + ClassLikeDeclaration c, AssociatedTypeDeclaration a, boolean inherited + ) { + associatedTypeParameter(c, a, inherited) + } or + TUnknownType() or + TUnknownTypeTypeParameter(int i) { i in [0 .. 20] } + +final class Type = TypeImpl; + +/** + * A type without type arguments. + */ +abstract private class TypeImpl extends TType { + /** + * Gets the `i`th positional type parameter of this type, if any. + * + * This excludes synthetic type parameters, such as associated types. + */ + abstract TypeParameter getPositionalTypeParameter(int i); + + /** + * Gets a type parameter of this type. + * + * This includes both positional type parameters and synthetic type parameters, + * such as associated types. + */ + TypeParameter getATypeParameter() { result = this.getPositionalTypeParameter(_) } + + /** Gets a textual representation of this type. */ + abstract string toString(); + + /** Gets the location of this type. */ + abstract Location getLocation(); +} + +/** + * A type representing a class-like declaration. + */ +class ClassLikeDeclarationType extends TypeImpl, TClassLikeDeclarationType { + ClassLikeDeclaration c; + + ClassLikeDeclarationType() { this = TClassLikeDeclarationType(c) } + + ClassLikeDeclaration getClassLikeDeclaration() { result = c } + + string getName() { result = c.getName() } + + override TypeParameter getPositionalTypeParameter(int i) { + result = TTypeParameterType(c.getTypeParameter(i)) + } + + override TypeParameter getATypeParameter() { + result = super.getATypeParameter() + or + result = TAssociatedTypeParameterType(c, _, _) + } + + override string toString() { result = c.getName() } + + override Location getLocation() { result = c.getLocation() } +} + +/** + * A pseudo type that does not correspond to any concrete type in the source code. + */ +abstract class PseudoType extends TypeImpl { } + +/** + * A type representing an unknown type. + */ +class UnknownType extends PseudoType, TUnknownType { + override TypeParameter getPositionalTypeParameter(int i) { result = TUnknownTypeTypeParameter(i) } + + override string toString() { result = "(unknown type)" } + + override Location getLocation() { result instanceof EmptyLocation } +} + +/** + * A type representing a closure parameter. + */ +class ClosureParameterPseudoType extends PseudoType, TClosureParameterPseudoType { + private Parameter param; + + ClosureParameterPseudoType() { this = TClosureParameterPseudoType(param) } + + Parameter getParam() { result = param } + + override TypeParameter getPositionalTypeParameter(int i) { none() } + + override string toString() { result = "(closure parameter " + param + ")" } + + override Location getLocation() { result = param.getLocation() } +} + +/** A type parameter. */ +abstract class TypeParameter extends TypeImpl { + override TypeParameter getPositionalTypeParameter(int i) { none() } + + abstract AstNode getDeclaringItem(); +} + +private class IdAstNode = + @unified_type_parameter or @unified_class_like_declaration or @unified_associated_type_declaration; + +private predicate id(IdAstNode x, IdAstNode y) { x = y } + +private predicate idOf(IdAstNode x, int y) = equivalenceRelation(id/2)(x, y) + +int idOfTypeParameterAstNode(AstNode node) { idOf(node, result) } + +/** A type parameter from source code. */ +class TypeParameterType extends TypeParameter, TTypeParameterType { + private Unified::TypeParameter typeParam; + + TypeParameterType() { this = TTypeParameterType(typeParam) } + + Unified::TypeParameter getTypeParameter() { result = typeParam } + + override ClassLikeDeclaration getDeclaringItem() { typeParam = result.getATypeParameter() } + + override string toString() { result = typeParam.getName() } + + override Location getLocation() { result = typeParam.getLocation() } +} + +/** + * An associated type viewed as a type parameter. + */ +class AssociatedTypeParameterType extends TypeParameter, TAssociatedTypeParameterType { + private Unified::ClassLikeDeclaration c; + private Unified::AssociatedTypeDeclaration assocTypeDecl; + private boolean inherited; + + AssociatedTypeParameterType() { this = TAssociatedTypeParameterType(c, assocTypeDecl, inherited) } + + Unified::AssociatedTypeDeclaration getAssociatedTypeDeclaration() { result = assocTypeDecl } + + override ClassLikeDeclaration getDeclaringItem() { result = c } + + override string toString() { + if inherited = true + then result = assocTypeDecl.getName() + " (inherited)" + else result = assocTypeDecl.getName() + } + + override Location getLocation() { + if inherited = true then result = c.getLocation() else result = assocTypeDecl.getLocation() + } +} + +/** + * A type parameter of the special `UnknownType`. + */ +class UnknownTypeTypeParameter extends TypeParameter, TUnknownTypeTypeParameter { + private int i; + + UnknownTypeTypeParameter() { this = TUnknownTypeTypeParameter(i) } + + override AstNode getDeclaringItem() { none() } + + override TypeParameter getPositionalTypeParameter(int j) { none() } + + override string toString() { result = "unknown type parameter " + i } + + override Location getLocation() { result instanceof EmptyLocation } +} diff --git a/unified/ql/lib/codeql/unified/internal/typeinference/TypeAbstraction.qll b/unified/ql/lib/codeql/unified/internal/typeinference/TypeAbstraction.qll new file mode 100644 index 000000000000..155c0d985ed9 --- /dev/null +++ b/unified/ql/lib/codeql/unified/internal/typeinference/TypeAbstraction.qll @@ -0,0 +1,19 @@ +private import unified as Unified +private import Type + +/** + * A type abstraction. I.e., a place in the program where type variables may + * be introduced. + */ +abstract class TypeAbstraction extends AstNode { + abstract TypeParameter getATypeParameter(); +} + +/** + * A class-like declaration. Unlike `ClassLikeDeclarationType`, this includes + * declarations that do not define a new type, such as `extension`s in Swift. + */ +final class ClassLikeDeclarationTypeAbstraction extends TypeAbstraction instanceof Unified::ClassLikeDeclaration +{ + override TypeParameter getATypeParameter() { this = result.getDeclaringItem() } +} diff --git a/unified/ql/lib/codeql/unified/internal/typeinference/TypeInference.qll b/unified/ql/lib/codeql/unified/internal/typeinference/TypeInference.qll new file mode 100644 index 000000000000..91352c5f5c4a --- /dev/null +++ b/unified/ql/lib/codeql/unified/internal/typeinference/TypeInference.qll @@ -0,0 +1,742 @@ +/** Provides functionality for inferring types. */ + +/* + * Known limitations: + * - Implicit constructors in classes and structs are not generated by the extractor + * - Patterns, including enum destructuring + * - Inferred qualifiers `.foo` + * - Type parameter bounds + * - Associated types on type parameters, e.g. `func foo(x : T) -> T.AssociatedType` + * - `Self` inside protocol extensions + * - Type parameters inherited in extensions + * - Primary associated types + * - Key paths + * - Overloading + * - Indexing expressions + * - Operations + * - Inherited constructors + */ + +private import codeql.util.Boolean +private import codeql.util.Option +private import codeql.util.Unit +private import Type +private import Type as T +private import TypeAbstraction +private import TypeAbstraction as TA +private import TypeMention +private import codeql.typeinference.internal.TypeInference +private import utils.test.InlineExpectationsTest +private import codeql.unified.internal.NameBinding +private import TypeInferencePlugin as Plugin +private import Plugin + +class Type = T::Type; + +private module Input1 implements InputSig1 { + private import Type as T + + class Type = T::Type; + + class PseudoType = T::PseudoType; + + class TypeParameter = T::TypeParameter; + + class TypeAbstraction = TA::TypeAbstraction; + + int getTypeParameterId(TypeParameter tp) { + tp = + rank[result](TypeParameter tp0, int kind, int id1, int id2 | + kind = 1 and + id1 = idOfTypeParameterAstNode(tp0.(TypeParameterType).getTypeParameter()) and + id2 = 0 + or + kind = 2 and + exists(ClassLikeDeclaration c, AssociatedTypeDeclaration a | + tp0 = TAssociatedTypeParameterType(c, a, _) and + id1 = idOfTypeParameterAstNode(c) and + id2 = idOfTypeParameterAstNode(a) + ) + or + kind = 3 and + tp0 = TUnknownTypeTypeParameter(id1) and + id2 = 0 + | + tp0 order by kind, id1, id2 + ) + } +} + +private import Input1 + +private module M1 = Make1; + +import M1 + +predicate getTypePathLimit = Input1::getTypePathLimit/0; + +predicate getTypeParameterId = Input1::getTypeParameterId/1; + +class TypePath = M1::TypePath; + +module TypePath = M1::TypePath; + +private module Input2 implements InputSig2 { + TypeMention getATypeParameterConstraint(TypeParameter tp) { + result = tp.(TypeParameterType).getTypeParameter().getBound() + } + + predicate conditionSatisfiesConstraint( + TypeAbstraction abs, TypeMention condition, TypeMention constraint, boolean transitive + ) { + transitive = true and + abs = + any(ClassLikeDeclaration c | + condition = c.getNameNode() and + constraint = c.getABaseType().getType() + ) + } + + predicate typeParameterIsFunctionallyDetermined(TypeParameter tp) { + tp instanceof AssociatedTypeParameterType + } + + predicate typeAbstractionHasAmbiguousConstraintAt( + TypeAbstraction abs, Type constraint, TypePath path + ) { + none() // todo + } +} + +private import Input2 + +private module M2 = Make2; + +import M2 + +private module Input3 implements InputSig3 { + private import unified as Unified + + predicate cacheRevRef() { exists(lookupMember(_)) implies any() } + + predicate inferTypeForDefaults = M3::inferType/2; + + class UnknownType = T::UnknownType; + + class BoolType = Plugin::BoolType; + + class AstNode = Unified::AstNode; + + class Expr = Unified::Expr; + + class Cast extends Expr, TypeCastExpr { + TypeMention getType() { result = TypeCastExpr.super.getType() } + } + + class Switch extends Expr, SwitchExpr { + Expr getExpr() { result = super.getValue() } + + Case getCase(int index) { result = super.getCase(index) } + } + + class Case extends SwitchCase { + AstNode getAPattern() { result = super.getPattern() } + + AstNode getBody() { result = super.getBody() } + } + + class ConditionalExpr extends Expr instanceof IfExpr { + Expr getCondition() { result = super.getCondition() } + + Expr getThen() { result = super.getThen() } + + Expr getElse() { result = super.getElse() } + } + + class BinaryExpr extends Expr, Unified::BinaryExpr { + Expr getLeftOperand() { result = super.getLeft() } + + Expr getRightOperand() { result = super.getRight() } + } + + class LogicalAndExpr extends BinaryExpr, Unified::LogicalAndExpr { } + + class LogicalOrExpr extends BinaryExpr, Unified::LogicalOrExpr { } + + class Assignment extends BinaryExpr, Unified::Assignment { } + + class AssignExpr extends Assignment, Unified::AssignExpr { } + + class ParenExpr extends Expr { + ParenExpr() { none() } + + Expr getExpr() { none() } + } + + /** Provides declarations with explicit AST node representations. */ + additional module AstDeclaration { + abstract class Declaration extends AstNode { + abstract TypeMention getDeclaringType(); + + abstract TypeMention getType(); + + abstract Identifier getNameNode(); + + pragma[nomagic] + predicate isMemberOf(ClassLikeDeclaration cls, Identifier i, string name) { + exists(NamespaceNode ns | + ns.isInstanceMemberNamespace(cls) and + ns.getMember(name).isIdentifier(i) and + i = this.getNameNode() + ) + } + } + + abstract class VariableDeclaration extends Declaration { + abstract AstNode getPattern(); + + abstract AstNode getInitializer(); + + predicate isCoercionSite() { none() } + + override TypeMention getDeclaringType() { none() } + + override Identifier getNameNode() { result = this.getPattern() } + } + + private class OrdinaryVariableDeclaration extends VariableDeclaration instanceof Unified::VariableDeclaration + { + override AstNode getPattern() { result = Unified::VariableDeclaration.super.getPattern() } + + override AstNode getInitializer() { result = super.getValue() } + + override TypeMention getType() { result = Unified::VariableDeclaration.super.getType() } + } + + class Field extends OrdinaryVariableDeclaration { + ClassLikeDeclaration cls; + + Field() { this = cls.getAMember() } + + override TypeMention getDeclaringType() { result = getClassLikeDeclarationTypeMention(cls) } + } + + private class EnumField_ extends Field instanceof EnumField { + override TypeMention getType() { result = super.getEnum().getNameNode() } + } + + class Parameter extends VariableDeclaration instanceof Unified::Parameter { + override AstNode getInitializer() { none() } + + override AstNode getPattern() { result = Unified::Parameter.super.getPattern() } + + override TypeMention getType() { result = Unified::Parameter.super.getType() } + } + + abstract class Callable extends Declaration instanceof Unified::Callable { + TypeMention getAdditionalTypeParameterConstraint(TypeParameter tp) { none() } // todo + + override TypeMention getDeclaringType() { + exists(ClassLikeDeclaration c | + result = getClassLikeDeclarationTypeMention(c) and + this = c.getAMember() + ) + } + + abstract TypeParameter getTypeParameter(int i); + + abstract Parameter getParameter(int i); + + abstract AstNode getBody(); + } + + private class FunctionDeclarationCallable extends Callable instanceof FunctionDeclaration { + override TypeParameterType getTypeParameter(int i) { + result.getTypeParameter() = FunctionDeclaration.super.getTypeParameter(i) + } + + override Parameter getParameter(int i) { result = FunctionDeclaration.super.getParameter(i) } + + override TypeMention getType() { result = super.getReturnType() } + + override AstNode getBody() { result = FunctionDeclaration.super.getBody() } + + override Identifier getNameNode() { result = FunctionDeclaration.super.getNameNode() } + } + + private class ConstructorDeclarationCallable extends Callable instanceof ConstructorDeclaration { + override TypeParameterType getTypeParameter(int i) { none() } + + override Parameter getParameter(int i) { + result = ConstructorDeclaration.super.getParameter(i) + } + + override TypeMention getType() { result = this.getDeclaringType() } + + override AstNode getBody() { result = ConstructorDeclaration.super.getBody() } + + override Identifier getNameNode() { result = ConstructorDeclaration.super.getNameNode() } + + override predicate isMemberOf(ClassLikeDeclaration cls, Identifier i, string name) { + this = cls.getAMember() and + i = this.getNameNode() and + name = i.getValue() + } + } + + class ClosureImpl extends Expr, Callable instanceof Unified::FunctionExpr { + override TypeParameterType getTypeParameter(int i) { none() } + + override Parameter getParameter(int i) { result = FunctionExpr.super.getParameter(i) } + + override TypeMention getType() { result = super.getReturnType() } + + override AstNode getBody() { result = FunctionExpr.super.getBody() } + + override Identifier getNameNode() { none() } + } + + private class EnumConstructorCallable extends ConstructorDeclarationCallable instanceof EnumConstructor + { + override TypeMention getType() { result = super.getEnum().getNameNode() } + + override Identifier getNameNode() { result = EnumConstructor.super.getNameNode() } + } + } + + // todo: enum constructors + private newtype TDeclaration = + TExplicitDeclaration(AstDeclaration::Declaration decl) or + TImplicitParameterDeclaration(LocalVariable v) { v.isImplicitReceiverParameter(_) } + + final class Declaration = DeclarationImpl; + + abstract private class DeclarationImpl extends TDeclaration { + abstract TypeMention getDeclaringType(); + + abstract TypeMention getType(); + + abstract Identifier getNameNode(); + + abstract string toString(); + + abstract Location getLocation(); + } + + additional class ExplicitDeclarationImpl extends DeclarationImpl, TExplicitDeclaration { + AstDeclaration::Declaration decl; + + ExplicitDeclarationImpl() { this = TExplicitDeclaration(decl) } + + AstDeclaration::Declaration getAstNode() { result = decl } + + override TypeMention getDeclaringType() { result = decl.getDeclaringType() } + + override TypeMention getType() { result = decl.getType() } + + override Identifier getNameNode() { result = decl.getNameNode() } + + override string toString() { result = decl.toString() } + + override Location getLocation() { result = decl.getLocation() } + } + + class Variable extends LocalNameBindingOutput::Local { + Expr getAnAccess() { result = super.getAnAccess() } + } + + final class VariableDeclaration = VariableDeclarationImpl; + + abstract private class VariableDeclarationImpl extends DeclarationImpl { + abstract AstNode getPattern(); + + abstract AstNode getInitializer(); + + predicate preservesInitializerType() { any() } + } + + private class ExplicitVariableDeclarationImpl extends VariableDeclarationImpl, + ExplicitDeclarationImpl + { + override AstDeclaration::VariableDeclaration decl; + + override AstNode getPattern() { result = decl.getPattern() } + + override AstNode getInitializer() { result = decl.getInitializer() } + } + + class Field extends ExplicitDeclarationImpl { + override AstDeclaration::Field decl; + } + + abstract class FieldAccess extends Expr { + abstract Expr getReceiver(); + + abstract Field getField(); + } + + private class MemberAccessExprFieldAccess extends FieldAccess, MemberAccessExpr { + override Expr getReceiver() { result = this.getBase() } + + override Field getField() { + // mutual recursion; resolving fields requires resolving types and vice versa + result.getNameNode() = lookupMember(this) + or + result.getNameNode() = getStaticBindingTarget(getIdentifierFromRef(this)) + } + } + + private Type getImplicitReceiverType(UnqualifiedMemberAccess uma, TypePath path) { + exists(ImplicitParameterDeclarationImpl p | + p.getVariable() = uma.getImplicitQualifierVariable() and + result = p.getType().getTypeAt(path) + ) + } + + private class UnqualifiedMemberAccessFieldAccess extends FieldAccess, UnqualifiedMemberAccess { + override Expr getReceiver() { none() } + + override Field getField() { result.getNameNode() = this.getTarget() } + } + + Type inferFieldAccessReceiverType(FieldAccess fa, TypePath path) { + result = inferType(fa.getReceiver(), path) + or + result = fa.getReceiver().(TypeMention).getTypeAt(path) + or + result = getImplicitReceiverType(fa, path) + } + + Type inferFieldAccessReceiverTypeContextual(Expr receiver, TypePath path) { + result = M3::inferFieldAccessReceiverTypeContextualDefault(_, receiver, path) + } + + class Return extends ReturnExpr { + Expr getExpr() { result = this.getValue() } + } + + final class Parameter = ParameterImpl; + + abstract private class ParameterImpl extends VariableDeclarationImpl { } + + private class ExplicitParameterImpl extends ParameterImpl, ExplicitDeclarationImpl { + override AstDeclaration::Parameter decl; + + override AstNode getPattern() { result = decl.getPattern() } + + override AstNode getInitializer() { result = decl.getInitializer() } + } + + private class ImplicitParameterDeclarationImpl extends ParameterImpl, + TImplicitParameterDeclaration + { + LocalVariable v; + + ImplicitParameterDeclarationImpl() { this = TImplicitParameterDeclaration(v) } + + LocalVariable getVariable() { result = v } + + override AstNode getPattern() { none() } + + override AstNode getInitializer() { none() } + + override TypeMention getDeclaringType() { none() } + + override TypeMention getType() { + result = getClassLikeDeclarationTypeMention(v.getDeclaringCallable().getEnclosingClass()) + } + + override Identifier getNameNode() { none() } + + override string toString() { result = v.toString() } + + override Location getLocation() { result = v.getLocation() } + } + + predicate implicitParameterDecl(Parameter p, Variable v) { + v = p.(ImplicitParameterDeclarationImpl).getVariable() + } + + class Callable extends ExplicitDeclarationImpl { + override AstDeclaration::Callable decl; + + TypeParameter getTypeParameter(int i) { result = decl.getTypeParameter(i) } + + TypeMention getAdditionalTypeParameterConstraint(TypeParameter tp) { + result = decl.getAdditionalTypeParameterConstraint(tp) + } + + Parameter getParameter(int i) { + result = TExplicitDeclaration(decl.getParameter(i - 1)) + or + i = 0 and + exists(LocalVariable v | + result = TImplicitParameterDeclaration(v) and + v.isImplicitReceiverParameter(decl) + ) + } + + AstNode getBody() { result = decl.getBody() } + } + + Callable getEnclosingCallable(AstNode node) { + result = TExplicitDeclaration(node.getEnclosingCallable()) + } + + class InvocationResolutionContext = Unit; + + class Invocation extends CallExpr { + Type getTypeQualifier(TypePath path) { + result = super.getCallee().(TypeMention).getTypeAt(path) + } + + Type getTypeArgument(int i, TypePath path) { none() } + + int getNumberOfArguments() { result = CallExpr.super.getNumberOfArguments() + 1 } + + Expr getArgument(int i) { + exists(boolean isFunctionExprInvoke | exists(resolveCallTarget(this, isFunctionExprInvoke)) | + i = 0 and + if isFunctionExprInvoke = true + then result = CallExpr.super.getCallee() + else result = CallExpr.super.getCallee().(MemberAccessExpr).getBase() + ) + or + result = CallExpr.super.getArgument(i - 1).getValue() + } + + Callable getTarget(InvocationResolutionContext c) { + result.getAstNode() = resolveCallTarget(this, _) and + exists(c) + } + + Callable getATargetForTypeQualifierMatching() { none() } + } + + Type inferInvocationArgumentType( + Invocation invocation, InvocationResolutionContext ctx, int i, TypePath path + ) { + exists(ctx) and + ( + exists(Type t | exists(getInvokeTarget(invocation, t)) | + i = 0 and + result = inferType(invocation.(CallExpr).getCallee(), path) + or + exists(TypePath prefix, TypePath suffix, int j | + functionInvokeSignature(t, invocation.getNumberOfArguments() - 1, j, i, prefix) and + result = inferType(invocation.getArgument(j + 1), suffix) and + path = prefix.append(suffix) + ) + ) + or + exists(resolveCallTarget(invocation, false)) and + ( + result = inferType(invocation.getArgument(i), path) + or + i = 0 and + result = getImplicitReceiverType(invocation.(CallExpr).getCallee(), path) + ) + ) + } + + Type inferInvocationArgumentTypeContextual(Expr arg, TypePath path) { + result = M3::inferInvocationArgumentTypeContextualDefault(_, _, _, arg, path) + } + + Type inferInvocationType(Invocation invocation, TypePath path) { + result = M3::inferInvocationTypeDefault(invocation, _, path) + } + + class Closure extends Callable, ExplicitDeclarationImpl { + override AstDeclaration::ClosureImpl decl; + + Expr getDefiningExpr() { result = decl } + } + + class ClosureParameterPseudoType extends T::ClosureParameterPseudoType { + Parameter getParameter() { result = TExplicitDeclaration(this.getParam()) } + } + + pragma[nomagic] + Type getClosureType(Closure c) { result = getFunctionExprType(c.getAstNode()) } + + pragma[nomagic] + TypePath getClosureParameterTypePath(Parameter p) { + exists(FunctionExpr fe, Type t, int i | + p = TExplicitDeclaration(fe.getParameter(i)) and + t = getFunctionExprType(fe) and + result = getFunctionExprParameterTypePath(t, fe.getNumberOfParameters(), i) + ) + } + + pragma[nomagic] + TypePath getClosureReturnTypePath(Closure c) { + result = getFunctionExprReturnTypePath(getClosureType(c)) + } + + predicate stepLanguageSpecific(AstNode n1, TypePath prefix1, AstNode n2, TypePath prefix2) { + n1 = n2.(Block).getLastStmt() and + prefix1.isEmpty() and + prefix2.isEmpty() + or + n1 = n2.(ArrayLiteral).getAnElement() and + prefix1.isEmpty() and + prefix2 = TypePath::singleton(getArrayElementTypeParameter()) + } + + Type inferTypeLanguageSpecific(AstNode n, TypePath path) { + result = Plugin::inferType(n, path) + or + n instanceof BooleanLiteral and + result instanceof BoolType and + path.isEmpty() + or + n instanceof IntLiteral and + result instanceof IntType and + path.isEmpty() + or + n instanceof StringLiteral and + result instanceof StringType and + path.isEmpty() + or + exists(ClassLikeDeclaration c | + c = n.(SuperExpr).getEnclosingClass() and + result = c.getBaseType(0).getType().(TypeMention).getTypeAt(path) + ) + or + // `Optional.none` has an unknown `Wrapper` type + exists(Field f, TypeParameter tp | + n.(FieldAccess).getField() = f and + f.(ExplicitDeclarationImpl).getAstNode() instanceof EnumField and + tp = f.getType().getType().getATypeParameter() and + path = TypePath::singleton(tp) and + not exists(n.(FieldAccess).getReceiver().(TypeMention).getTypeAt(path)) and + result instanceof UnknownType + ) + } + + pragma[nomagic] + Type inferTypeCertainLanguageSpecific(AstNode n, TypePath path) { none() } +} + +private module M3 = Make3; + +predicate inferType = M3::inferType/1; + +predicate inferType = M3::inferType/2; + +predicate inferTypeCertain = M3::inferTypeCertain/2; + +module Consistency = M3::Consistency; + +module CachedStage = M3::CachedStage; + +pragma[nomagic] +private predicate lookupMember0(MemberAccessExpr mae, ClassLikeDeclaration cls, string name) { + cls = inferType(mae.getBase()).(ClassLikeDeclarationType).getClassLikeDeclaration() and + name = mae.getMemberName() +} + +cached +Identifier lookupMember(MemberAccessExpr mae) { + exists(ClassLikeDeclaration cls, Input3::ExplicitDeclarationImpl decl, string name | + lookupMember0(mae, cls, name) and + decl.getAstNode().isMemberOf(cls, result, name) + ) +} + +pragma[nomagic] +private Callable getInvokeTarget(CallExpr ce, Type t) { + t = inferType(ce.getCallee()) and + result = getFunctionInvoke(t) +} + +// Does not yet take overloading into account +Callable resolveCallTarget(CallExpr ce, boolean isFunctionExprInvoke) { + exists(NameBinding b | b = getStaticBindingTarget(getIdentifierFromRef(ce.getCallee())) | + // object creation + exists(ClassLikeDeclaration cls, ConstructorDeclaration init | + cls.getNameNode() = b and + init = cls.getAMember() and + result = init + ) + or + result.(Input3::AstDeclaration::Declaration).getNameNode() = b + ) and + isFunctionExprInvoke = false + or + result.(Input3::AstDeclaration::Declaration).getNameNode() = lookupMember(ce.getCallee()) and + isFunctionExprInvoke = false + or + result = getInvokeTarget(ce, _) and + isFunctionExprInvoke = true +} + +VariableDeclaration resolveFieldAccess(Expr access) { + result = access.(Input3::FieldAccess).getField().getAstNode() +} + +private predicate typeTestAstNodeRepr(AstNode n, string repr) { + repr = [n.toString(), n.(Identifier).getValue(), "." + n.(MemberAccessExpr).getMemberName()] +} + +module TypeTest implements TestSig { + private module M = M3::TypeTest; + + import M + + predicate hasOptionalResult = M::hasOptionalResult/4; +} + +/** Provides predicates for debugging the type inference implementation. */ +private module Debug { + // Locatable getRelevantLocatable() { + // exists(string filepath, int startline, int startcolumn, int endline, int endcolumn | + // result.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and + // filepath.matches("%/main.rs") and + // startline = 103 + // ) + // } + // Type debugInferType(AstNode n, TypePath path) { + // n = getRelevantLocatable() and + // result = inferType(n, path) + // } + // Addressable debugResolveCallTarget(InvocationExpr c, boolean dispatch) { + // c = getRelevantLocatable() and + // result = resolveCallTarget(c, dispatch) + // } + // predicate debugConditionSatisfiesConstraint( + // TypeAbstraction abs, TypeMention condition, TypeMention constraint, boolean transitive + // ) { + // abs = getRelevantLocatable() and + // Input2::conditionSatisfiesConstraint(abs, condition, constraint, transitive) + // } + // predicate debugInferShorthandSelfType(ShorthandSelfParameterMention self, TypePath path, Type t) { + // self = getRelevantLocatable() and + // t = self.getTypeAt(path) + // } + // predicate debugTypeMention(TypeMention tm, TypePath path, Type type) { + // tm = getRelevantLocatable() and + // tm.getTypeAt(path) = type + // } + predicate atLimit = M3::Debug::atLimit/1; + + predicate inferTypeForNodeAtLimit = M3::Debug::inferTypeForNodeAtLimit/2; + + predicate countTypesForNodeAtLimit = M3::Debug::countTypesForNodeAtLimit/2; + + predicate maxTypes = M3::Debug::maxTypes/4; + + predicate maxTypePath = M3::Debug::maxTypePath/4; + + predicate maxTypePaths = M3::Debug::maxTypePaths/4; + // Type debugInferTypeCertain(AstNode n, TypePath path) { + // n = getRelevantLocatable() and + // result = inferTypeCertain(n, path) + // } + // Type debugInferCertainNonUniqueType(AstNode n, TypePath path) { + // n = getRelevantLocatable() and + // Consistency::nonUniqueCertainType(n, path) and + // result = inferTypeCertain(n, path) + // } +} diff --git a/unified/ql/lib/codeql/unified/internal/typeinference/TypeInferenceConsistency.qll b/unified/ql/lib/codeql/unified/internal/typeinference/TypeInferenceConsistency.qll new file mode 100644 index 000000000000..247ad8b24c7c --- /dev/null +++ b/unified/ql/lib/codeql/unified/internal/typeinference/TypeInferenceConsistency.qll @@ -0,0 +1,19 @@ +/** + * Provides classes for recognizing type inference inconsistencies. + */ + +private import Type +private import TypeMention +private import TypeInference +private import TypeInference::Consistency as Consistency +import TypeInference::Consistency + +query predicate illFormedTypeMention(TypeMention tm) { + Consistency::illFormedTypeMention(tm) and + tm.fromSource() +} + +query predicate nonUniqueCertainType(AstNode n, TypePath path) { + Consistency::nonUniqueCertainType(n, path) and + n.fromSource() // Only include inconsistencies in the source. +} diff --git a/unified/ql/lib/codeql/unified/internal/typeinference/TypeInferencePlugin.qll b/unified/ql/lib/codeql/unified/internal/typeinference/TypeInferencePlugin.qll new file mode 100644 index 000000000000..42a38f97f303 --- /dev/null +++ b/unified/ql/lib/codeql/unified/internal/typeinference/TypeInferencePlugin.qll @@ -0,0 +1,152 @@ +/** + * Provides an interface for language-specific type inference logic. + */ + +private import Type +private import TypeInference +private import codeql.util.Unit + +private module Plugins { + private import TypeInferencePluginSwift +} + +class TypeInferencePlugin extends Unit { + /** Gets the boolean type which will be assigned to boolean literals. */ + abstract Type getBoolType(); + + /** Gets the integer type which will be assigned to integer literals. */ + abstract Type getIntType(); + + /** Gets the string type which will be assigned to string literals. */ + abstract Type getStringType(); + + /** Gets the type parameter representing the element type of an array. */ + abstract TypeParameter getArrayElementTypeParameter(); + + /** + * Gets the type of the given function expression. + * + * For example `Fn` in Rust (which does not depend on `fe`). + */ + bindingset[fe] + abstract Type getFunctionExprType(FunctionExpr fe); + + /** + * Gets the type path for the `i`th parameter of the given function type + * when the function type has the given arity. + * + * For example `"Args.Ti"` in Rust, where `Args` is the type argument of + * `Fn` and `Ti` is the `i`th type parameter of the tuple type with arity + * `arity`. + */ + bindingset[t, arity, i] + abstract TypePath getFunctionExprParameterTypePath(Type t, int arity, int i); + + /** + * Gets the type path for the return type of the given function type. + * + * For example `"Output"` in Rust, where `Output` is the associated type + * of `Fn`. + */ + bindingset[t] + abstract TypePath getFunctionExprReturnTypePath(Type t); + + /** + * Gets the `invoke` function for the given function type. + * + * For example the `call` method of the `Fn` trait in Rust. + */ + abstract Callable getFunctionInvoke(Type t); + + /** + * Holds if the `i`th syntactic argument in a call to the `invoke` function + * belonging to `t` should map to position `j` and type path `path`. + * + * For example, in Rust, in a call `closure(arg0, arg1)` the 0th argument + * maps to `(1, "T0")` and the second argument maps to `(1, "T1")`, where `T0` + * is the first type parameter of the 2-tuple type and `T1` is the second type + * parameter. + */ + bindingset[t, arity, i] + abstract predicate functionInvokeSignature(Type t, int arity, int i, int j, TypePath path); + + /** Gets the tuple type with the given arity. */ + abstract Type getTupleType(int arity); + + /** Holds if `case` is an enum case constructor of `enum` with identifier `i`. */ + abstract predicate isEnumConstructor( + ClassLikeDeclaration enum, ConstructorDeclaration case, Identifier i + ); + + /** Holds if `field` is an enum field of `enum`. */ + abstract predicate isEnumField(ClassLikeDeclaration enum, VariableDeclaration field); + + /** Gets the inferred type for the given AST node and type path. */ + Type inferType(AstNode n, TypePath path) { none() } +} + +class BoolType extends Type { + BoolType() { this = any(TypeInferencePlugin p).getBoolType() } +} + +class IntType extends Type { + IntType() { this = any(TypeInferencePlugin p).getIntType() } +} + +class StringType extends Type { + StringType() { this = any(TypeInferencePlugin p).getStringType() } +} + +TypeParameter getArrayElementTypeParameter() { + result = any(TypeInferencePlugin p).getArrayElementTypeParameter() +} + +bindingset[fe] +Type getFunctionExprType(FunctionExpr fe) { + result = any(TypeInferencePlugin p).getFunctionExprType(fe) +} + +bindingset[t, arity, i] +TypePath getFunctionExprParameterTypePath(Type t, int arity, int i) { + result = any(TypeInferencePlugin pl).getFunctionExprParameterTypePath(t, arity, i) +} + +TypePath getFunctionExprReturnTypePath(Type t) { + result = any(TypeInferencePlugin pl).getFunctionExprReturnTypePath(t) +} + +class TupleType extends Type { + int arity; + + TupleType() { this = any(TypeInferencePlugin p).getTupleType(arity) } + + int getArity() { result = arity } +} + +class EnumConstructor extends ConstructorDeclaration { + private ClassLikeDeclaration enum; + private Identifier id; + + EnumConstructor() { any(TypeInferencePlugin p).isEnumConstructor(enum, this, id) } + + ClassLikeDeclaration getEnum() { result = enum } + + Identifier getNameNode() { result = id } +} + +class EnumField extends VariableDeclaration { + private ClassLikeDeclaration enum; + + EnumField() { any(TypeInferencePlugin p).isEnumField(enum, this) } + + ClassLikeDeclaration getEnum() { result = enum } +} + +Type inferType(AstNode n, TypePath path) { result = any(TypeInferencePlugin p).inferType(n, path) } + +Callable getFunctionInvoke(Type t) { result = any(TypeInferencePlugin p).getFunctionInvoke(t) } + +bindingset[t, arity, i] +predicate functionInvokeSignature(Type t, int arity, int i, int j, TypePath path) { + any(TypeInferencePlugin p).functionInvokeSignature(t, arity, i, j, path) +} diff --git a/unified/ql/lib/codeql/unified/internal/typeinference/TypeInferencePluginSwift.qll b/unified/ql/lib/codeql/unified/internal/typeinference/TypeInferencePluginSwift.qll new file mode 100644 index 000000000000..1f70e7223794 --- /dev/null +++ b/unified/ql/lib/codeql/unified/internal/typeinference/TypeInferencePluginSwift.qll @@ -0,0 +1,171 @@ +/** + * Provides Swift-specific type inference logic. + */ + +private import Type +private import TypeInference +private import TypeInferencePlugin as Plugin +private import codeql.unified.internal.Builtins + +private class StructType extends ClassLikeDeclarationType { + StructType() { c.getAModifier().getValue() = "struct" } +} + +private class BuiltinType extends StructType { + BuiltinType() { this.getClassLikeDeclaration() instanceof BuiltinClassLikeDeclaration } +} + +private class BoolType extends BuiltinType { + BoolType() { this.getName() = "Bool" } +} + +private class IntType extends BuiltinType { + IntType() { this.getName() = "Int" } +} + +private class StringType extends BuiltinType { + StringType() { this.getName() = "String" } +} + +private class ArrayType extends BuiltinType { + ArrayType() { this.getName() = "Array" } +} + +class FunctionType extends BuiltinType { + FunctionType() { this.getName() = "Function" } +} + +pragma[nomagic] +TypeParameter getFunctionArgsTypeParameter() { + result = any(FunctionType t).getPositionalTypeParameter(0) +} + +pragma[nomagic] +TypeParameter getFunctionReturnTypeParameter() { + result = any(FunctionType t).getPositionalTypeParameter(1) +} + +/** Gets the path to a closure's `index`th parameter type, where the arity is `arity`. */ +pragma[nomagic] +private TypePath functionParameterPath(int arity, int index) { + result = + TypePath::cons(getFunctionArgsTypeParameter(), + TypePath::singleton(getTupleTypeParameter(arity, index))) +} + +pragma[nomagic] +private TypePath functionReturnPath() { + result = TypePath::singleton(getFunctionReturnTypeParameter()) +} + +private class TupleType extends BuiltinType { + private int arity; + + TupleType() { arity = this.getName().regexpCapture("Tuple([0-9]+)", 1).toInt() } + + int getArity() { result = arity } +} + +pragma[nomagic] +TypeParameter getTupleTypeParameter(int arity, int i) { + result = any(TupleType t | t.getArity() = arity).getPositionalTypeParameter(i) +} + +private class Enum extends ClassLikeDeclaration { + Enum() { this.getAModifier().getValue() = "enum" } +} + +private class EnumConstructor extends ConstructorDeclaration { + private Enum e; + private Identifier id; + + EnumConstructor() { + exists(ClassLikeDeclaration c | + c = e.getAMember() and + c.getAModifier().getValue() = "enum_case" and + this = c.getAMember() and + id = c.getNameNode() + ) + } + + Identifier getNameNode() { result = id } + + Enum getEnum() { result = e } +} + +private class EnumField extends VariableDeclaration { + private Enum e; + + EnumField() { + this = e.getAMember() and + this.getAModifier().getValue() = "enum_case" + } + + Enum getEnum() { result = e } +} + +private predicate inferTypeAlias = inferType/2; + +private class SwiftTypeInferencePlugin extends Plugin::TypeInferencePlugin { + override Type getBoolType() { result instanceof BoolType } + + override Type getIntType() { result instanceof IntType } + + override Type getStringType() { result instanceof StringType } + + override TypeParameter getArrayElementTypeParameter() { + result = any(ArrayType t).getPositionalTypeParameter(0) + } + + bindingset[fe] + override Type getFunctionExprType(FunctionExpr fe) { + result instanceof FunctionType and + exists(fe) + } + + bindingset[t] + override TypePath getFunctionExprParameterTypePath(Type t, int arity, int i) { + result = functionParameterPath(arity, i) and exists(t) + } + + bindingset[t] + override TypePath getFunctionExprReturnTypePath(Type t) { + result = functionReturnPath() and exists(t) + } + + pragma[nomagic] + override FunctionDeclaration getFunctionInvoke(Type t) { + result = t.(FunctionType).getClassLikeDeclaration().getAMember() and + result.getName() = "invoke" + } + + bindingset[t, arity, i] + override predicate functionInvokeSignature(Type t, int arity, int i, int j, TypePath path) { + j = 1 and + path = TypePath::singleton(getTupleTypeParameter(arity, i)) and + exists(t) + } + + override Type getTupleType(int arity) { result.(TupleType).getArity() = arity } + + override predicate isEnumConstructor( + ClassLikeDeclaration enum, ConstructorDeclaration case, Identifier i + ) { + case = + any(EnumConstructor ec | + enum = ec.getEnum() and + i = ec.getNameNode() + ) + } + + override predicate isEnumField(ClassLikeDeclaration enum, VariableDeclaration field) { + enum = field.(EnumField).getEnum() + } + + override Type inferType(AstNode n, TypePath path) { + // todo: approximation for now + n instanceof BinaryExpr and + result = inferTypeAlias(n.(BinaryExpr).getLeft(), path) and + result = inferTypeAlias(n.(BinaryExpr).getRight(), path) + } +} diff --git a/unified/ql/lib/codeql/unified/internal/typeinference/TypeMention.qll b/unified/ql/lib/codeql/unified/internal/typeinference/TypeMention.qll new file mode 100644 index 000000000000..939e1e44a26a --- /dev/null +++ b/unified/ql/lib/codeql/unified/internal/typeinference/TypeMention.qll @@ -0,0 +1,159 @@ +private import unified as Unified +private import Type +private import TypeInference +private import TypeInferencePlugin as Plugin +private import codeql.unified.internal.StaticNameBinding +private import codeql.unified.internal.ExprPositions + +/** An AST node that mentions a type. */ +abstract class TypeMention extends AstNode { + /** + * Gets the type mentioned at `path`. + */ + pragma[nomagic] + abstract Type getTypeAt(TypePath path); + + /** + * Gets the type mentioned at the root of this type mention. + */ + final Type getType() { result = this.getTypeAt(TypePath::nil()) } +} + +private Type resolveType(Identifier access) { + exists(NameBinding b | b = getStaticBindingTarget(access) | + b = result.(ClassLikeDeclarationType).getClassLikeDeclaration().getNameNode() + or + b = result.(TypeParameterType).getTypeParameter().getNameNode() + ) +} + +abstract private class ExprTypeMention extends TypeMention, Expr { + abstract Type getRootType(); +} + +private class InTypeContextTypeMention extends ExprTypeMention { + InTypeContextTypeMention() { isInTypeContext(this) } + + private Type getRootType0() { + result = resolveType(this) + or + result = Plugin::getFunctionExprType(this) + or + result.(Plugin::TupleType).getArity() = this.(TupleExpr).getNumberOfElements() + } + + override Type getRootType() { + result = this.getRootType0() + or + not exists(this.getRootType0()) and + result instanceof UnknownType + } + + override Type getTypeAt(TypePath path) { + result = this.getRootType() and + path.isEmpty() + or + exists( + ClassLikeDeclaration c, AssociatedTypeDeclaration a, ClassLikeDeclaration base, + AssociatedTypeParameterType baseTp, string name + | + // protocol Base { + // associatedtype BaseTp + // } + associatedTypeParameterInherited(c, a, base, this, name) and + baseTp = TAssociatedTypeParameterType(base, a, _) + | + // protocol Sub : Base { + // ^^^^ // `BaseTp` is instantiated with `BaseTp (inherited)` + // } + path = TypePath::singleton(baseTp) and + result = TAssociatedTypeParameterType(c, a, true) + or + // struct S : Base { + // ^^^^ // `BaseTp` is instantiated with `String` + // typealias BaseTp = String + // } + exists(TypeAliasDeclaration alias, TypePath suffix | + alias = c.getAMember() and + alias.getName() = name and + path = TypePath::cons(baseTp, suffix) and + result = alias.getType().(TypeMention).getTypeAt(suffix) + ) + ) + or + exists(FunctionExpr fe, Type t, TypePath prefix, TypePath suffix | + this = fe and + t = Plugin::getFunctionExprType(fe) and + path = prefix.append(suffix) + | + exists(int i | + prefix = Plugin::getFunctionExprParameterTypePath(t, fe.getNumberOfParameters(), i) and + result = fe.getParameter(i).getType().(TypeMention).getTypeAt(suffix) + ) + or + prefix = Plugin::getFunctionExprReturnTypePath(t) and + result = fe.getReturnType().(TypeMention).getTypeAt(suffix) + ) + or + this = + any(TupleExpr te | + exists(Plugin::TupleType tt, int i, TypePath suffix | + tt.getArity() = te.getNumberOfElements() and + result = te.getElement(i).getValue().(TypeMention).getTypeAt(suffix) and + path = TypePath::cons(tt.getPositionalTypeParameter(i), suffix) + ) + ) + } +} + +private class IdentifierTypeMention extends ExprTypeMention, Identifier { + IdentifierTypeMention() { exists(resolveType(this)) } + + override Type getRootType() { result = resolveType(this) } + + override Type getTypeAt(TypePath path) { + result = this.getRootType() and + path.isEmpty() + } +} + +private class GenericTypeExprTypeMention extends TypeMention, GenericTypeExpr { + override Type getTypeAt(TypePath path) { + exists(ExprTypeMention base | base = this.getBase() | + result = base.getRootType() and + path.isEmpty() + or + exists(Type root, int i, TypeParameter tp, TypePath suffix | + root = base.getRootType() and + tp = root.getPositionalTypeParameter(i) and + result = this.getTypeArgument(i).(TypeMention).getTypeAt(suffix) and + path = TypePath::cons(tp, suffix) + ) + ) + } +} + +/** A class declaration mentions itself. */ +private class ClassLikeDeclarationTypeMention extends TypeMention, Identifier { + private ClassLikeDeclaration c; + + ClassLikeDeclarationTypeMention() { this = c.getNameNode() } + + ClassLikeDeclarationType getRootType() { c = result.getClassLikeDeclaration() } + + ClassLikeDeclaration getClassLikeDeclaration() { result = c } + + override Type getTypeAt(TypePath path) { + result = this.getRootType() and + path.isEmpty() + or + result = this.getRootType().getATypeParameter() and + path = TypePath::singleton(result) + } +} + +TypeMention getClassLikeDeclarationTypeMention(ClassLikeDeclaration c) { + result = c.getNameNode() + or + result = c.getExtensionTarget() +} diff --git a/unified/ql/lib/qlpack.yml b/unified/ql/lib/qlpack.yml index 84261b14adc7..3eec7c0a100a 100644 --- a/unified/ql/lib/qlpack.yml +++ b/unified/ql/lib/qlpack.yml @@ -11,6 +11,7 @@ dependencies: codeql/ssa: ${workspace} codeql/dataflow: ${workspace} codeql/namebinding: ${workspace} + codeql/typeinference: ${workspace} codeql/util: ${workspace} warnOnImplicitThis: true compileForOverlayEval: true diff --git a/unified/ql/lib/utils/test/ExternalLocationPostProcessing.ql b/unified/ql/lib/utils/test/ExternalLocationPostProcessing.ql new file mode 100644 index 000000000000..bf2d21d9b65c --- /dev/null +++ b/unified/ql/lib/utils/test/ExternalLocationPostProcessing.ql @@ -0,0 +1,9 @@ +/** + * @kind test-postprocess + */ + +private import unified +private import codeql.util.test.ExternalLocationPostProcessing +import Make + +private string getSourceLocationPrefix() { sourceLocationPrefix(result) } diff --git a/unified/ql/lib/utils/test/TestUtils.qll b/unified/ql/lib/utils/test/TestUtils.qll index 4a232e984e78..91ae2f068095 100644 --- a/unified/ql/lib/utils/test/TestUtils.qll +++ b/unified/ql/lib/utils/test/TestUtils.qll @@ -1,11 +1,14 @@ private import unified private import CommentUtil private import codeql.unified.internal.NameBinding +private import codeql.unified.internal.typeinference.TypeInferencePlugin private string deriveClassName(ClassLikeDeclaration cls) { not exists(cls.getEnclosingClass()) and result = cls.getName() or + result = getStaticBindingTarget(cls.getExtensionTarget()).getValue() + or result = deriveClassName(cls.getEnclosingClass()) + "." + cls.getName() } @@ -32,3 +35,46 @@ predicate nameBinding(NameBinding v, string alias) { alias = defaultName(v) ) } + +private string getCallableName(Callable c) { + result = c.(AccessorDeclaration).getName() + or + result = c.(ConstructorDeclaration).getName() + or + c instanceof DestructorDeclaration and + result = "" + or + result = c.(FunctionDeclaration).getName() + or + c instanceof InitializerDeclaration and + result = "" +} + +private string defaultCallableName(Callable c) { + exists(ClassLikeDeclaration cls | + c = cls.getAMember() and + result = deriveClassName(cls) + "." + getCallableName(c) + ) + or + not c = any(ClassLikeDeclaration cls).getAMember() and + result = getCallableName(c) + or + exists(ClassLikeDeclaration enum | + enum = c.(EnumConstructor).getEnum() and + result = deriveClassName(enum) + "." + c.getEnclosingClass().getName() + ) +} + +private predicate callableAt(Callable c, string filepath, int line) { + c.getLocation().hasLocationInfo(filepath, line, _, _, _) +} + +/** Holds if the callable `c` has been assigned the given `alias` by a comment in the test code. */ +predicate callableName(Callable c, string alias) { + exists(string filepath, int line | callableAt(c, filepath, line) | + keyValueCommentAt(filepath, line, "name", alias) + or + not keyValueCommentAt(filepath, line, "name", _) and + alias = defaultCallableName(c) + ) +} diff --git a/unified/ql/test/library-tests/BasicTest/test.ql b/unified/ql/test/library-tests/BasicTest/test.ql index 165cb1be9a0e..a3f7947eea98 100644 --- a/unified/ql/test/library-tests/BasicTest/test.ql +++ b/unified/ql/test/library-tests/BasicTest/test.ql @@ -8,8 +8,12 @@ query predicate namedPattern(NamedPattern node, string value) { value = node.get query predicate unsupported(UnsupportedNode node, string value) { value = node.getValue() } -query predicate rawStringValue(StringLiteral e, string value) { value = e.getValue() } +query predicate rawStringValue(StringLiteral e, string value) { + e.fromSource() and value = e.getValue() +} -query predicate exprStringValue(Expr e, string value) { value = e.getStringValue() } +query predicate exprStringValue(Expr e, string value) { + e.fromSource() and value = e.getStringValue() +} query predicate unexpectedUnaryTuple(TupleExpr tuple) { count(tuple.getAnElement()) = 1 } diff --git a/unified/ql/test/library-tests/controlflow/CONSISTENCY/TypeInferenceConsistency.expected b/unified/ql/test/library-tests/controlflow/CONSISTENCY/TypeInferenceConsistency.expected new file mode 100644 index 000000000000..c45f45d7c2a9 --- /dev/null +++ b/unified/ql/test/library-tests/controlflow/CONSISTENCY/TypeInferenceConsistency.expected @@ -0,0 +1,3 @@ +nonUniqueCertainType +| cfg.swift:160:7:160:15 | xOptional | | +| cfg.swift:161:26:161:34 | xOptional | | diff --git a/unified/ql/test/library-tests/dataflow/calls.swift b/unified/ql/test/library-tests/dataflow/calls.swift index 9f2fedf4d3c8..1735fc4d6d45 100644 --- a/unified/ql/test/library-tests/dataflow/calls.swift +++ b/unified/ql/test/library-tests/dataflow/calls.swift @@ -90,13 +90,13 @@ func t8() { func read3() { sink(field) // no flow self.store() - sink(field) // $ MISSING: hasValueFlow=t8.1 // self.store() not yet resolved by call graph + sink(field) // $ hasValueFlow=t8.1 } func read4() { sink(field) // no flow self.store() - sink(self.field) // $ MISSING: hasValueFlow=t8.1 // self.store() not yet resolved by call graph + sink(self.field) // $ hasValueFlow=t8.1 } func read5() { @@ -114,13 +114,13 @@ func t8() { func read7() { sink(self.field) // no flow self.store() - sink(field) // $ MISSING: hasValueFlow=t8.1 // self.store() not yet resolved by call graph + sink(field) // $ hasValueFlow=t8.1 } func read8() { sink(self.field) // no flow self.store() - sink(self.field) // $ MISSING: hasValueFlow=t8.1 // self.store() not yet resolved by call graph + sink(self.field) // $ hasValueFlow=t8.1 } } } diff --git a/unified/ql/test/library-tests/dataflow/test.expected b/unified/ql/test/library-tests/dataflow/test.expected index 09bfb86d7540..13bbe3739beb 100644 --- a/unified/ql/test/library-tests/dataflow/test.expected +++ b/unified/ql/test/library-tests/dataflow/test.expected @@ -27,11 +27,17 @@ edges | calls.swift:67:10:67:10 | b [field] | calls.swift:67:10:67:16 | ... .field | provenance | | | calls.swift:75:13:75:17 | field | calls.swift:81:18:81:22 | field | provenance | | | calls.swift:75:13:75:17 | field | calls.swift:87:18:87:21 | self [field] | provenance | | +| calls.swift:75:13:75:17 | field | calls.swift:93:18:93:22 | field | provenance | | +| calls.swift:75:13:75:17 | field | calls.swift:99:18:99:21 | self [field] | provenance | | | calls.swift:75:13:75:17 | field | calls.swift:105:18:105:22 | field | provenance | | | calls.swift:75:13:75:17 | field | calls.swift:111:18:111:21 | self [field] | provenance | | +| calls.swift:75:13:75:17 | field | calls.swift:117:18:117:22 | field | provenance | | +| calls.swift:75:13:75:17 | field | calls.swift:123:18:123:21 | self [field] | provenance | | | calls.swift:75:21:75:34 | source(...) | calls.swift:75:13:75:17 | field | provenance | | | calls.swift:87:18:87:21 | self [field] | calls.swift:87:18:87:27 | ... .field | provenance | | +| calls.swift:99:18:99:21 | self [field] | calls.swift:99:18:99:27 | ... .field | provenance | | | calls.swift:111:18:111:21 | self [field] | calls.swift:111:18:111:27 | ... .field | provenance | | +| calls.swift:123:18:123:21 | self [field] | calls.swift:123:18:123:27 | ... .field | provenance | | | implicit-self.swift:16:9:16:12 | [post] self [x] | implicit-self.swift:17:14:17:17 | self [x] | provenance | | | implicit-self.swift:16:9:16:14 | ... .x | implicit-self.swift:16:9:16:12 | [post] self [x] | provenance | | | implicit-self.swift:16:18:16:31 | source(...) | implicit-self.swift:16:9:16:14 | ... .x | provenance | | @@ -212,9 +218,15 @@ nodes | calls.swift:81:18:81:22 | field | semmle.label | field | | calls.swift:87:18:87:21 | self [field] | semmle.label | self [field] | | calls.swift:87:18:87:27 | ... .field | semmle.label | ... .field | +| calls.swift:93:18:93:22 | field | semmle.label | field | +| calls.swift:99:18:99:21 | self [field] | semmle.label | self [field] | +| calls.swift:99:18:99:27 | ... .field | semmle.label | ... .field | | calls.swift:105:18:105:22 | field | semmle.label | field | | calls.swift:111:18:111:21 | self [field] | semmle.label | self [field] | | calls.swift:111:18:111:27 | ... .field | semmle.label | ... .field | +| calls.swift:117:18:117:22 | field | semmle.label | field | +| calls.swift:123:18:123:21 | self [field] | semmle.label | self [field] | +| calls.swift:123:18:123:27 | ... .field | semmle.label | ... .field | | implicit-self.swift:16:9:16:12 | [post] self [x] | semmle.label | [post] self [x] | | implicit-self.swift:16:9:16:14 | ... .x | semmle.label | ... .x | | implicit-self.swift:16:18:16:31 | source(...) | semmle.label | source(...) | @@ -412,8 +424,12 @@ testFailures | calls.swift:67:10:67:16 | ... .field | calls.swift:62:19:62:32 | source(...) | calls.swift:67:10:67:16 | ... .field | $@ | calls.swift:62:19:62:32 | source(...) | source(...) | | calls.swift:81:18:81:22 | field | calls.swift:75:21:75:34 | source(...) | calls.swift:81:18:81:22 | field | $@ | calls.swift:75:21:75:34 | source(...) | source(...) | | calls.swift:87:18:87:27 | ... .field | calls.swift:75:21:75:34 | source(...) | calls.swift:87:18:87:27 | ... .field | $@ | calls.swift:75:21:75:34 | source(...) | source(...) | +| calls.swift:93:18:93:22 | field | calls.swift:75:21:75:34 | source(...) | calls.swift:93:18:93:22 | field | $@ | calls.swift:75:21:75:34 | source(...) | source(...) | +| calls.swift:99:18:99:27 | ... .field | calls.swift:75:21:75:34 | source(...) | calls.swift:99:18:99:27 | ... .field | $@ | calls.swift:75:21:75:34 | source(...) | source(...) | | calls.swift:105:18:105:22 | field | calls.swift:75:21:75:34 | source(...) | calls.swift:105:18:105:22 | field | $@ | calls.swift:75:21:75:34 | source(...) | source(...) | | calls.swift:111:18:111:27 | ... .field | calls.swift:75:21:75:34 | source(...) | calls.swift:111:18:111:27 | ... .field | $@ | calls.swift:75:21:75:34 | source(...) | source(...) | +| calls.swift:117:18:117:22 | field | calls.swift:75:21:75:34 | source(...) | calls.swift:117:18:117:22 | field | $@ | calls.swift:75:21:75:34 | source(...) | source(...) | +| calls.swift:123:18:123:27 | ... .field | calls.swift:75:21:75:34 | source(...) | calls.swift:123:18:123:27 | ... .field | $@ | calls.swift:75:21:75:34 | source(...) | source(...) | | implicit-self.swift:17:14:17:19 | ... .x | implicit-self.swift:16:18:16:31 | source(...) | implicit-self.swift:17:14:17:19 | ... .x | $@ | implicit-self.swift:16:18:16:31 | source(...) | source(...) | | implicit-self.swift:23:14:23:14 | x | implicit-self.swift:22:13:22:26 | source(...) | implicit-self.swift:23:14:23:14 | x | $@ | implicit-self.swift:22:13:22:26 | source(...) | source(...) | | implicit-self.swift:29:14:29:19 | ... .x | implicit-self.swift:28:13:28:26 | source(...) | implicit-self.swift:29:14:29:19 | ... .x | $@ | implicit-self.swift:28:13:28:26 | source(...) | source(...) | diff --git a/unified/ql/test/library-tests/type-inference/CONSISTENCY/CfgConsistency.expected b/unified/ql/test/library-tests/type-inference/CONSISTENCY/CfgConsistency.expected new file mode 100644 index 000000000000..f54308ecd5ef --- /dev/null +++ b/unified/ql/test/library-tests/type-inference/CONSISTENCY/CfgConsistency.expected @@ -0,0 +1,7 @@ +consistencyOverview +| deadEnd | 4 | +deadEnd +| generics.swift:46:8:46:17 | Entry | +| generics.swift:47:8:47:22 | Entry | +| pattern_matching.swift:9:8:9:15 | Entry | +| pattern_matching.swift:10:8:10:34 | Entry | diff --git a/unified/ql/test/library-tests/type-inference/basics.swift b/unified/ql/test/library-tests/type-inference/basics.swift new file mode 100644 index 000000000000..029aa728fa53 --- /dev/null +++ b/unified/ql/test/library-tests/type-inference/basics.swift @@ -0,0 +1,63 @@ +var topLevelDecl: Int = 0 +0 +topLevelDecl + 1 // $ type=topLevelDecl:Int + +class C { + var myInt: Int + init(n: Int) { + myInt = n // $ type=n:Int field=C.myInt + } + + func getMyInt() -> Int { + return myInt // $ type=myInt:Int field=C.myInt + } +} + +class Derived: C { + init() { + super.init(n: 0) // $ type=super:C target=C.init + } + + func callGetMyInt() -> Int { + let x = getMyInt() // $ type=x:Int target=C.getMyInt + return x + } +} + +class Generic { + var value: T + init(v: T) { + value = v // $ type=v:T field=Generic.value + } + + func getValue() -> T { + return value // $ type=value:T field=Generic.value + } +} + +class GenericDerived: Generic { + init() { + super.init(v: 0) // $ type=super@Generic:Int target=Generic.init + } +} + +func testGeneric() { + let g = Generic(v: 42) // $ type=g@Generic:Int target=Generic.init + let x = g.getValue() // $ type=x:Int target=Generic.getValue + + let gd = GenericDerived() // $ type=gd:GenericDerived target=GenericDerived.init + let y = gd.getValue() // $ type=y:Int target=Generic.getValue +} + +// --- Extensions --- + +extension C { + func doubled() -> Int { + return myInt * 2 // $ type=myInt:Int field=C.myInt + } +} + +func testExtension() { + let obj = C(n: 10) // $ target=C.init + let d = obj.doubled() // $ type=d:Int target=C.doubled +} diff --git a/unified/ql/test/library-tests/type-inference/classes.swift b/unified/ql/test/library-tests/type-inference/classes.swift new file mode 100644 index 000000000000..04051568685c --- /dev/null +++ b/unified/ql/test/library-tests/type-inference/classes.swift @@ -0,0 +1,205 @@ +// --- Static methods --- + +class MathUtils { + static func square(x: Int) -> Int { + return x * x // $ type=x:Int + } + + class func cube(x: Int) -> Int { + return x * x * x // $ type=x:Int + } +} + +func testStaticMethods() { + let s = MathUtils.square(x: 4) // $ type=s:Int target=MathUtils.square + let cu = MathUtils.cube(x: 3) // $ type=cu:Int target=MathUtils.cube +} + +// --- Simple overloading --- + +class Overloaded { + func process(_ x: Int) -> Int { // name=process1 + return x + 1 // $ type=x:Int + } + + func process(_ s: String) -> String { // name=process2 + return s // $ type=s:String + } +} + +func testOverloading() { + let o = Overloaded() // $ MISSING: target=Overloaded.init + let r1 = o.process(42) // $ MISSING: type=r1:Int target=Overloaded.process1 + let r2 = o.process("hello") // $ MISSING: type=r2:String target=Overloaded.process2 +} + +// --- Structs and methods --- + +struct Matrix { + var data: [[Int]] + + init(data: [[Int]]) { + self.data = data // $ field=Matrix.data + } + + func rowCount() -> Int { + return data.count // $ field=Matrix.data + } +} + +func testSubscripts() { + let m = Matrix(data: [[1, 2], [3, 4]]) // $ target=Matrix.init + let rc = m.rowCount() // $ type=rc:Int target=Matrix.rowCount +} + +// --- Nested types --- + +class Outer { + class Inner { + var value: Int + + init(value: Int) { + self.value = value // $ type=value:Int field=Outer.Inner.value + } + + func getValue() -> Int { + return self.value // $ type=.value:Int field=Outer.Inner.value + } + } +} + +func testNestedTypes() { + let inner = Outer.Inner(value: 99) // $ type=inner:Inner target=Outer.Inner.init + let v = inner.getValue() // $ type=v:Int target=Outer.Inner.getValue +} + +// --- Method chaining --- + +class Builder { + var value: Int = 0 + + init() {} + + func set(_ v: Int) -> Builder { + value = v // $ type=v:Int field=Builder.value + return self + } + + func add(_ v: Int) -> Builder { + value += v // $ type=v:Int field=Builder.value + return self + } + + func build() -> Int { + return value // $ type=value:Int field=Builder.value + } +} + +func testChaining() { + let b = Builder() // $ type=b:Builder target=Builder.init + let result = b.set(10).add(5).build() // $ type=result:Int target=Builder.set target=Builder.add target=Builder.build +} + +// --- Default parameter values --- + +class Config { + init() {} + + func setup(retries: Int = 3, timeout: Double = 30.0) -> Int { + return retries // $ type=retries:Int + } +} + +func testDefaultParams() { + let cfg = Config() // $ type=cfg:Config target=Config.init + let r1 = cfg.setup() // $ type=r1:Int target=Config.setup + let r2 = cfg.setup(retries: 5) // $ type=r2:Int target=Config.setup + let r3 = cfg.setup(retries: 2, timeout: 60.0) // $ type=r3:Int target=Config.setup +} + +// --- Computed properties accessed via methods --- + +class Temperature { + var celsius: Double + + init(celsius: Double) { + self.celsius = celsius // $ type=celsius:Double field=Temperature.celsius + } + + func toCelsius() -> Double { + return celsius // $ type=celsius:Double field=Temperature.celsius + } + + func toFahrenheit() -> Double { + return celsius * 9.0 / 5.0 + 32.0 // $ type=celsius:Double field=Temperature.celsius + } +} + +func testTemperature() { + let t = Temperature(celsius: 100.0) // $ type=t:Temperature target=Temperature.init + let c = t.toCelsius() // $ type=c:Double target=Temperature.toCelsius + let f = t.toFahrenheit() // $ type=f:Double target=Temperature.toFahrenheit +} + +// --- Inheritance with overriding --- + +class Animal { + init() {} + + func speak() -> String { + return "..." + } +} + +class Dog: Animal { + override init() { + super.init() // $ target=Animal.init + } + + override func speak() -> String { + return "Woof" + } + + func fetch() -> String { + return "ball" + } +} + +class Cat: Animal { + override init() { + super.init() // $ target=Animal.init + } + + override func speak() -> String { + return "Meow" + } +} + +func testOverriding() { + let d = Dog() // $ type=d:Dog target=Dog.init + let ds = d.speak() // $ type=ds:String target=Dog.speak + let df = d.fetch() // $ type=df:String target=Dog.fetch + + let ct = Cat() // $ type=ct:Cat target=Cat.init + let cs = ct.speak() // $ type=cs:String target=Cat.speak +} + +// --- Mutating methods on structs --- + +struct Counter { + var count: Int = 0 + + mutating func increment() { + count += 1 // $ type=count:Int field=Counter.count + } + + func getCount() -> Int { + return count // $ type=count:Int field=Counter.count + } +} + +func testMutating() { + var ctr = Counter() // $ MISSING: type=ctr:Counter target=init() + ctr.increment() // $ MISSING: target=Counter.increment + let val = ctr.getCount() // $ MISSING: type=val:Int target=Counter.getCount +} diff --git a/unified/ql/test/library-tests/type-inference/closures.swift b/unified/ql/test/library-tests/type-inference/closures.swift new file mode 100644 index 000000000000..2f84578727a1 --- /dev/null +++ b/unified/ql/test/library-tests/type-inference/closures.swift @@ -0,0 +1,49 @@ +func testExplicitClosureCall() { + let addOne = { value in // $ type=value:Int + value + 1 + } + let result = addOne(41) // $ target=Function.invoke + _ = result // $ type=result:Int +} + +func callWithIntCallback(_ callback: (Int) -> String) -> String { + callback(42) // $ target=Function.invoke +} + +func callWithGenericCallback(_ callback: (T1) -> Void, _ arg: T1) -> T1 { + callback(arg) // $ target=Function.invoke + return arg +} + +func testImplicitClosureCall() { + let result = callWithIntCallback { value in + String(value) // $ type=value:Int target=String.init + } // $ target=callWithIntCallback + _ = result // $ type=result:String + + let genericResult = callWithGenericCallback( + { value in // $ type=value:Bool + // do nothing + }, false) // $ target=callWithGenericCallback + _ = genericResult // $ type=genericResult:Bool +} + +class C { + var f: (Int) -> Int // name=f_closure + + func f(_ value: Int) -> Int { // name=f_method + return 0 + } + + var f2: (Int) -> Int // name=f2_closure + + init(f: @escaping (Int) -> Int) { + self.f = f // $ field=f_closure + self.f2 = f // $ field=f2_closure + } + + func callsMethod(_ value: Int) -> Int { + self.f(value) // $ target=f_method $ SPURIOUS: field=f_closure target=Function.invoke + return self.f2(value) // $ field=f2_closure target=Function.invoke + } +} diff --git a/unified/ql/test/library-tests/type-inference/context.swift b/unified/ql/test/library-tests/type-inference/context.swift new file mode 100644 index 000000000000..a46e9f899d72 --- /dev/null +++ b/unified/ql/test/library-tests/type-inference/context.swift @@ -0,0 +1,7 @@ +func foo() { + let numbers = [1, 2, 3] // $ type=numbers@Array:Int + + let strings = numbers.map { x in // $ type=x:Int + String(x) // $ target=String.init + } // $ target=Array.map +} diff --git a/unified/ql/test/library-tests/type-inference/fields.swift b/unified/ql/test/library-tests/type-inference/fields.swift new file mode 100644 index 000000000000..6ba3df38c8f3 --- /dev/null +++ b/unified/ql/test/library-tests/type-inference/fields.swift @@ -0,0 +1,43 @@ +class FieldBase { + var inheritedField: Int = 0 +} + +class FieldContainer: FieldBase { + var storedField: String = "stored" + var genericField: T + + init(genericField: T) { + self.genericField = genericField // $ type=.genericField:T field=FieldContainer.genericField + } + + func getStoredField() -> String { + return storedField // $ type=storedField:String field=FieldContainer.storedField + } + + func getGenericField() -> T { + return self.genericField // $ type=.genericField:T field=FieldContainer.genericField + } +} + +struct StaticFieldContainer { + static var staticField: Bool = true +} + +struct NestedField { + var value: Double +} + +struct OuterField { + var nested: NestedField +} + +func testFieldAccesses() { + let container = FieldContainer(genericField: 42) // $ target=FieldContainer.init + let stored = container.storedField // $ type=.storedField:String field=FieldContainer.storedField + let generic = container.genericField // $ type=.genericField:Int field=FieldContainer.genericField + let inherited = container.inheritedField // $ type=.inheritedField:Int field=FieldBase.inheritedField + let staticValue = StaticFieldContainer.staticField // $ type=.staticField:Bool field=StaticFieldContainer.staticField + + let outer = OuterField(nested: NestedField(value: 1.0)) // $ MISSING: target=OuterField.init target=NestedField.init + let nestedValue = outer.nested.value // $ MISSING: type=.nested:NestedField field=OuterField.nested type=.value:Double field=NestedField.value +} diff --git a/unified/ql/test/library-tests/type-inference/generics.swift b/unified/ql/test/library-tests/type-inference/generics.swift new file mode 100644 index 000000000000..a81d03c2d03b --- /dev/null +++ b/unified/ql/test/library-tests/type-inference/generics.swift @@ -0,0 +1,274 @@ +// --- Generic functions --- + +func identity(_ x: T) -> T { + return x // $ type=x:T +} + +func makePair(_ a: A, _ b: B) -> (A, B) { + return (a, b) // $ type=a:A +} + +func testGenericFunctions() { + let i = identity(42) // $ type=i:Int target=identity + let s = identity("hello") // $ type=s:String target=identity + let p = makePair(1, "two") // $ target=makePair +} + +// --- Generic structs --- + +struct Pair { + var first: A + var second: B + + init(first: A, second: B) { + self.first = first // $ type=first:A field=Pair.first + self.second = second // $ type=second:B field=Pair.second + } + + func getFirst() -> A { + return first // $ type=first:A field=Pair.first + } + + func getSecond() -> B { + return second // $ type=second:B field=Pair.second + } +} + +func testGenericStruct() { + let p = Pair(first: 1, second: "x") // $ target=Pair.init type=p@Pair:Int type=p@Pair:String + let f = p.getFirst() // $ type=f:Int target=Pair.getFirst + let sc = p.getSecond() // $ type=sc:String target=Pair.getSecond +} + +// --- Enums with associated values --- + +enum Result { + case success(T) + case failure(String) + + func getValue() -> T? { + switch self { + case .success(let v): // $ MISSING: target=Result.success + return v // $ MISSING: type=v:T + case .failure: // $ MISSING: target=Result.failure + return nil + } + } +} + +func testEnum() { + let r = Result.success(42) // $ type=r@Result:Int target=Result.success + let v = r.getValue() // $ target=Result.getValue + + let r2: Result = .success(42) // $ type=r2@Result:Int $ MISSING: target=Result.success + let v2 = r2.getValue() // $ target=Result.getValue +} + +// --- Closures and type inference --- + +func applyTransform(_ value: T, _ transform: (T) -> U) -> U { + let result = transform(value) // $ type=result:U target=Function.invoke + return result +} + +func testClosures() { + let result = applyTransform(5, { x in x * 2 }) // $ target=applyTransform type=result:Int + let strings = applyTransform( // $ type=strings:String + 10, + { + x in String(x) // $ type=x:Int target=String.init + }) // $ target=applyTransform +} + +// --- Generic class with constraints --- + +protocol MyProtocol { + associatedtype MyType + + func foo() -> Self + + func bar() -> MyType +} + +class Wrapper { + var inner: T + + init(_ inner: T) { + self.inner = inner // $ type=inner:T field=Wrapper.inner + } + + func get() -> T { + return inner // $ type=inner:T field=Wrapper.inner + } + + func callFoo() -> T { + let x = inner.foo() // $ field=Wrapper.inner $ MISSING: type=x:T target=MyProtocol.foo + return x + } + + func callBar() -> T.MyType { + let x = inner.bar() // $ field=Wrapper.inner $ MISSING: type=x:MyType target=MyProtocol.bar + return x + } +} + +extension Int: MyProtocol { + typealias MyType = String + + func foo() -> Int { + return self * 2 // $ type=self:Int + } + + func bar() -> String { + return "number" + } +} + +func testConstrainedGeneric() { + let w = Wrapper(42) // $ type=w@Wrapper:Int target=Wrapper.init + let v = w.get() // $ type=v:Int target=Wrapper.get + let z = w.callFoo() // $ type=z:Int target=Wrapper.callFoo +} + +// --- Generics and inheritance --- + +class Base { + var value1: T1 + var value2: T2 + + init(_ v1: T1, _ v2: T2) { + self.value1 = v1 // $ type=v1:T1 field=Base.value1 + self.value2 = v2 // $ type=v2:T2 field=Base.value2 + } + + func getValue1() -> T1 { + return value1 // $ type=value1:T1 field=Base.value1 + } + + func getValue2() -> T2 { + return value2 // $ type=value2:T2 field=Base.value2 + } +} + +class Derived: Base { + init(_ v1: T1, _ v2: T2) { + super.init(v2, v1) // $ type=v2:T2 type=v1:T1 target=Base.init + } +} + +class DerivedDerived: Derived { + init(_ v: D) { + super.init(v, true) // $ type=v:D target=Derived.init + } +} + +func testDerived() { + let d = Derived(1, "x") // $ type=d@Derived:Int type=d@Derived:String target=Derived.init + let v1 = d.getValue1() // $ type=v1:String target=Base.getValue1 + let v2 = d.getValue2() // $ type=v2:Int target=Base.getValue2 + + let dd = DerivedDerived("hello") // $ type=dd@DerivedDerived:String target=DerivedDerived.init + let vv1 = dd.getValue1() // $ type=vv1:Bool target=Base.getValue1 + let vv2 = dd.getValue2() // $ type=vv2:String target=Base.getValue2 +} + +// --- Generics and protocols --- + +protocol MyProtocol2 { + associatedtype MyType + + func baz() -> MyType +} + +extension MyProtocol2 { + func foo() -> Self { + return self // $ MISSING: type=self:Self + } +} + +class MyClass { + var value: T + + init(_ value: T) { + self.value = value // $ type=value:T field=MyClass.value + } +} + +extension MyClass: MyProtocol2 { + typealias MyType = T + + func baz() -> T { + return value // $ field=MyClass.value $ MISSING: type=value:T + } +} + +func callFoo(_ c: T) -> T { + return c.foo() // $ MISSING: target=MyProtocol2.foo +} + +func callBaz(_ c: T) -> T.MyType { + return c.baz() // $ MISSING: target=MyProtocol2.baz +} + +func testProtocolExtension() { + let c = MyClass(42) // $ type=c@MyClass:Int target=MyClass.init + let s = c.foo() // $ target=MyProtocol2.foo $ MISSING: type=s@MyClass:Int + let v = c.baz() // $ target=MyClass.baz $ MISSING: type=v:Int + let v2 = callBaz(c) // $ target=callBaz $ MISSING: type=v2:Int +} + +// --- Inherited associated types --- + +protocol BaseAssociatedTypeProtocol { + associatedtype Value + + func baseValue() -> Value +} + +protocol SubAssociatedTypeProtocol: BaseAssociatedTypeProtocol { + func subValue() -> Value +} + +struct StringAssociatedType: SubAssociatedTypeProtocol { + typealias Value = String + + func baseValue() -> String { + return "base" + } + + func subValue() -> String { + return "sub" + } +} + +func getInheritedAssociatedType(_ value: T) -> T.Value { + return value.subValue() // $ MISSING: target=SubAssociatedTypeProtocol.subValue +} + +func testInheritedAssociatedType() { + let value = getInheritedAssociatedType(StringAssociatedType()) // $ target=getInheritedAssociatedType $ MISSING: type=value:String +} + +// --- Primary associated types --- + +protocol PrimaryAssociatedTypeProtocol { + associatedtype Element + + func element() -> Element +} + +struct IntPrimaryAssociatedType: PrimaryAssociatedTypeProtocol { + typealias Element = Int + + func element() -> Int { + return 42 + } +} + +func getPrimaryAssociatedType(_ value: some PrimaryAssociatedTypeProtocol) -> Int { + return value.element() // $ MISSING: target=PrimaryAssociatedTypeProtocol.element +} + +func testPrimaryAssociatedType() { + let value = getPrimaryAssociatedType(IntPrimaryAssociatedType()) // $ type=value:Int target=getPrimaryAssociatedType +} diff --git a/unified/ql/test/library-tests/type-inference/key_paths.swift b/unified/ql/test/library-tests/type-inference/key_paths.swift new file mode 100644 index 000000000000..b900888f095d --- /dev/null +++ b/unified/ql/test/library-tests/type-inference/key_paths.swift @@ -0,0 +1,210 @@ +// --- Key-path expressions: basic property access --- + +struct Point { + var x: Double + var y: Double + + init(x: Double, y: Double) { + self.x = x // $ type=x:Double field=Point.x + self.y = y // $ type=y:Double field=Point.y + } + + func distanceFromOrigin() -> Double { + return (x * x + y * y).squareRoot() // $ field=Point.x field=Point.x field=Point.y field=Point.y + } +} + +struct Line { + var start: Point + var end: Point + + init(start: Point, end: Point) { + self.start = start // $ field=Line.start + self.end = end // $ field=Line.end + } +} + +func testBasicKeyPaths() { + let kpX = \Point.x + let kpY = \Point.y + + let p = Point(x: 3.0, y: 4.0) // $ type=p:Point target=Point.init + let xVal = p[keyPath: kpX] // $ MISSING: type=xVal:Double + let yVal = p[keyPath: kpY] // $ MISSING: type=yVal:Double +} + +// --- Key-path expressions: nested property access --- + +func testNestedKeyPaths() { + let kpStartX = \Line.start.x + let kpEndY = \Line.end.y + + let s = Point(x: 0.0, y: 0.0) // $ target=Point.init + let e = Point(x: 1.0, y: 1.0) // $ target=Point.init + let line = Line(start: s, end: e) // $ target=Line.init + let startX = line[keyPath: kpStartX] // $ MISSING: type=startX:Double + let endY = line[keyPath: kpEndY] // $ MISSING: type=endY:Double +} + +// --- Key-path expressions: identity (\.self) --- + +func testSelfKeyPath() { + let kpSelf = \Int.self + let val = 42[keyPath: kpSelf] // $ MISSING: type=val:Int +} + +// --- Key-path expressions: optional chaining --- + +struct Person { + var name: String + var address: Address? + + init(name: String, address: Address?) { + self.name = name // $ type=name:String field=Person.name + self.address = address // $ field=Person.address + } +} + +struct Address { + var city: String + var zip: String + + init(city: String, zip: String) { + self.city = city // $ type=city:String field=Address.city + self.zip = zip // $ type=zip:String field=Address.zip + } +} + +func testOptionalChainingKeyPaths() { + let kpCity = \Person.address?.city + let addr = Address(city: "NYC", zip: "10001") // $ target=Address.init + let person = Person(name: "Alice", address: addr) // $ target=Person.init + + let city = person[keyPath: kpCity] // $ MISSING: type=city@Optional:String +} + +// --- Key-path expressions: used as function arguments --- + +struct Employee { + var name: String + var salary: Int + + init(name: String, salary: Int) { + self.name = name // $ type=name:String field=Employee.name + self.salary = salary // $ type=salary:Int field=Employee.salary + } +} + +func extractField(_ items: [T], keyPath: KeyPath) -> [V] { + return items.map { $0[keyPath: keyPath] } // $ target=Array.map +} + +func testKeyPathAsArgument() { + let e1 = Employee(name: "Alice", salary: 100) // $ target=Employee.init + let e2 = Employee(name: "Bob", salary: 200) // $ target=Employee.init + let employees = [e1, e2] + let names = extractField(employees, keyPath: \.name) // $ target=extractField $ MISSING: target=extractField(_:keyPath:) + let name = names[0] // $ MISSING: type=name:String + let salaries = extractField(employees, keyPath: \.salary) // $ target=extractField $ MISSING: target=extractField(_:keyPath:) + let salary = salaries[0] // $ MISSING: type=salary:Int +} + +// --- Key-path expressions: with generics --- + +class KPContainer { + var item: T + + init(item: T) { + self.item = item // $ type=item:T field=KPContainer.item + } +} + +func testGenericKeyPaths() { + let kp = \KPContainer.item + let c = KPContainer(item: 42) // $ target=KPContainer.init + let v = c[keyPath: kp] // $ MISSING: type=v:Int +} + +// --- Key-path expressions: writable key paths and mutation --- + +func testWritableKeyPaths() { + var p = Point(x: 1.0, y: 2.0) // $ type=p:Point target=Point.init + let kpX = \Point.x + p[keyPath: kpX] = 10.0 + let newX = p[keyPath: kpX] // $ MISSING: type=newX:Double +} + +// --- Key-path expressions: appending key paths --- + +func testKeyPathAppending() { + let kpStart = \Line.start + let kpX = \Point.x + let kpStartX = kpStart.appending(path: kpX) + + let s = Point(x: 5.0, y: 6.0) // $ target=Point.init + let e = Point(x: 7.0, y: 8.0) // $ target=Point.init + let line = Line(start: s, end: e) // $ target=Line.init + let val = line[keyPath: kpStartX] // $ MISSING: type=val:Double +} + +// --- Key-path expressions: shorthand in higher-order functions --- + +func testKeyPathInMap() { + let e1 = Employee(name: "Alice", salary: 100) // $ target=Employee.init + let e2 = Employee(name: "Bob", salary: 200) // $ target=Employee.init + let employees = [e1, e2] + let names = employees.map(\.name) // $ target=Array.map + let name = names[0] // $ MISSING: type=name:String + let salaries = employees.map(\.salary) // $ target=Array.map + let salary = salaries[0] // $ MISSING: type=salary:Int +} + +// --- Key-path expressions: class hierarchy --- + +class Shape2 { + var color: String + + init(color: String) { + self.color = color // $ type=color:String field=Shape2.color + } +} + +class Circle2: Shape2 { + var radius: Double + + init(color: String, radius: Double) { + self.radius = radius // $ type=radius:Double field=Circle2.radius + super.init(color: color) // $ target=Shape2.init + } +} + +func testInheritedKeyPaths() { + let kpColor = \Circle2.color + let kpRadius = \Circle2.radius + + let c = Circle2(color: "red", radius: 5.0) // $ type=c:Circle2 target=Circle2.init + let col = c[keyPath: kpColor] // $ MISSING: type=col:String + let rad = c[keyPath: kpRadius] // $ MISSING: type=rad:Double +} + +// --- Key-path expressions: tuple element access --- + +func testTupleKeyPath() { + let kp0 = \(Int, String).0 + let kp1 = \(Int, String).1 + let tuple = (42, "hello") + let first = tuple[keyPath: kp0] // $ MISSING: type=first:Int + let second = tuple[keyPath: kp1] // $ MISSING: type=second:String +} + +// --- Key-path expressions: array/dictionary subscript --- + +func testSubscriptKeyPaths() { + let kpFirst = \[Int][0] + let arr = [10, 20, 30] + let first = arr[keyPath: kpFirst] // $ MISSING: type=first:Int + + let kpKey = \[String: Int]["x"] + let dict = ["x": 1, "y": 2] + let val = dict[keyPath: kpKey] // $ MISSING: type=val:Int? +} diff --git a/unified/ql/test/library-tests/type-inference/lub.swift b/unified/ql/test/library-tests/type-inference/lub.swift new file mode 100644 index 000000000000..4abf1c16bc9f --- /dev/null +++ b/unified/ql/test/library-tests/type-inference/lub.swift @@ -0,0 +1,15 @@ +class A { + public init() {} +} + +class B: A { + public override init() {} +} + +class C: A {} + +func foo() { + let b = B() // $ type=b:B target=B.init + let c = C() // $ MISSING: type=c:C target=C.init + let x = 2 > 3 ? b : c // $ MISSING: type=x:A +} diff --git a/unified/ql/test/library-tests/type-inference/overload_resolution.swift b/unified/ql/test/library-tests/type-inference/overload_resolution.swift new file mode 100644 index 000000000000..6b6059da4be9 --- /dev/null +++ b/unified/ql/test/library-tests/type-inference/overload_resolution.swift @@ -0,0 +1,445 @@ +// --- Overload by parameter type --- + +class OverloadByType { + public init() {} + + func handle(_ x: Int) -> String { // name=OverloadByType.handle1 + return "int" + } + + func handle(_ x: Double) -> String { // name=OverloadByType.handle2 + return "double" + } + + func handle(_ x: String) -> String { // name=OverloadByType.handle3 + return "string" + } + + func handle(_ x: Bool) -> String { // name=OverloadByType.handle4 + return "bool" + } +} + +func testOverloadByType() { + let o = OverloadByType() // $ target=OverloadByType.init + let r1 = o.handle(42) // $ type=r1:String target=OverloadByType.handle1 $ SPURIOUS: target=OverloadByType.handle2 target=OverloadByType.handle3 target=OverloadByType.handle4 + let r2 = o.handle(3.14) // $ type=r2:String target=OverloadByType.handle2 $ SPURIOUS: target=OverloadByType.handle1 target=OverloadByType.handle3 target=OverloadByType.handle4 + let r3 = o.handle("hi") // $ type=r3:String target=OverloadByType.handle3 $ SPURIOUS: target=OverloadByType.handle1 target=OverloadByType.handle2 target=OverloadByType.handle4 + let r4 = o.handle(true) // $ type=r4:String target=OverloadByType.handle4 $ SPURIOUS: target=OverloadByType.handle1 target=OverloadByType.handle2 target=OverloadByType.handle3 +} + +// --- Overload by argument label --- + +class OverloadByLabel { + public init() {} + + func configure(width: Int) -> String { // name=OverloadByLabel.configure1 + return "width" + } + + func configure(height: Int) -> String { // name=OverloadByLabel.configure2 + return "height" + } + + func configure(width: Int, height: Int) -> String { // name=OverloadByLabel.configure3 + return "both" + } + + func configure(size: Int) -> String { // name=OverloadByLabel.configure4 + return "size" + } +} + +func testOverloadByLabel() { + let o = OverloadByLabel() // $ target=OverloadByLabel.init + let r1 = o.configure(width: 10) // $ type=r1:String target=OverloadByLabel.configure1 $ SPURIOUS: target=OverloadByLabel.configure2 target=OverloadByLabel.configure3 target=OverloadByLabel.configure4 + let r2 = o.configure(height: 20) // $ type=r2:String target=OverloadByLabel.configure2 $ SPURIOUS: target=OverloadByLabel.configure1 target=OverloadByLabel.configure3 target=OverloadByLabel.configure4 + let r3 = o.configure(width: 10, height: 20) // $ type=r3:String target=OverloadByLabel.configure3 $ SPURIOUS: target=OverloadByLabel.configure1 target=OverloadByLabel.configure2 target=OverloadByLabel.configure4 + let r4 = o.configure(size: 30) // $ type=r4:String target=OverloadByLabel.configure4 $ SPURIOUS: target=OverloadByLabel.configure1 target=OverloadByLabel.configure2 target=OverloadByLabel.configure3 +} + +// --- Overload by arity (number of parameters) --- + +class OverloadByArity { + public init() {} + + func compute() -> Int { // name=OverloadByArity.compute1 + return 0 + } + + func compute(_ x: Int) -> Int { // name=OverloadByArity.compute2 + return x + } + + func compute(_ x: Int, _ y: Int) -> Int { // name=OverloadByArity.compute3 + return x + y + } + + func compute(_ x: Int, _ y: Int, _ z: Int) -> Int { // name=OverloadByArity.compute4 + return x + y + z + } +} + +func testOverloadByArity() { + let o = OverloadByArity() // $ target=OverloadByArity.init + let r0 = o.compute() // $ type=r0:Int target=OverloadByArity.compute1 $ SPURIOUS: target=OverloadByArity.compute2 target=OverloadByArity.compute3 target=OverloadByArity.compute4 + let r1 = o.compute(1) // $ type=r1:Int target=OverloadByArity.compute2 $ SPURIOUS: target=OverloadByArity.compute1 target=OverloadByArity.compute3 target=OverloadByArity.compute4 + let r2 = o.compute(1, 2) // $ type=r2:Int target=OverloadByArity.compute3 $ SPURIOUS: target=OverloadByArity.compute1 target=OverloadByArity.compute2 target=OverloadByArity.compute4 + let r3 = o.compute(1, 2, 3) // $ type=r3:Int target=OverloadByArity.compute4 $ SPURIOUS: target=OverloadByArity.compute1 target=OverloadByArity.compute2 target=OverloadByArity.compute3 +} + +// --- Overload by return type (contextual type) --- + +class OverloadByReturn { + public init() {} + + func create() -> Int { // name=OverloadByReturn.create1 + return 0 + } + + func create() -> String { // name=OverloadByReturn.create2 + return "" + } + + func create() -> Double { // name=OverloadByReturn.create3 + return 0.0 + } +} + +func testOverloadByReturn() { + let o = OverloadByReturn() // $ target=OverloadByReturn.init + let r1: Int = o.create() // $ type=r1:Int target=OverloadByReturn.create1 $ SPURIOUS: target=OverloadByReturn.create2 target=OverloadByReturn.create3 + let r2: String = o.create() // $ type=r2:String target=OverloadByReturn.create2 $ SPURIOUS: target=OverloadByReturn.create1 target=OverloadByReturn.create3 + let r3: Double = o.create() // $ type=r3:Double target=OverloadByReturn.create3 $ SPURIOUS: target=OverloadByReturn.create1 target=OverloadByReturn.create2 +} + +// --- Overload: generic vs non-generic (non-generic preferred) --- + +class OverloadGenericVsConcrete { + public init() {} + + func process(_ x: Int) -> String { // name=OverloadGenericVsConcrete.process1 + return "concrete" + } + + func process(_ x: T) -> String { // name=OverloadGenericVsConcrete.process2 + return "generic" + } +} + +func testOverloadGenericVsConcrete() { + let o = OverloadGenericVsConcrete() // $ target=OverloadGenericVsConcrete.init + let r1 = o.process(42) // $ type=r1:String target=OverloadGenericVsConcrete.process1 $ SPURIOUS: target=OverloadGenericVsConcrete.process2 + let r2 = o.process("hello") // $ type=r2:String target=OverloadGenericVsConcrete.process2 $ SPURIOUS: target=OverloadGenericVsConcrete.process1 + let r3 = o.process(true) // $ type=r3:String target=OverloadGenericVsConcrete.process2 $ SPURIOUS: target=OverloadGenericVsConcrete.process1 +} + +// --- Overload: free functions by parameter type --- + +func freeOverload(_ x: Int) -> String { // name=freeOverload1 + return "int" +} + +func freeOverload(_ x: String) -> String { // name=freeOverload2 + return "string" +} + +func freeOverload(_ x: Double) -> String { // name=freeOverload3 + return "double" +} + +func testFreeOverload() { + let r1 = freeOverload(42) // $ type=r1:String target=freeOverload1 $ SPURIOUS: target=freeOverload2 target=freeOverload3 + let r2 = freeOverload("hi") // $ type=r2:String target=freeOverload2 $ SPURIOUS: target=freeOverload1 target=freeOverload3 + let r3 = freeOverload(1.5) // $ type=r3:String target=freeOverload3 $ SPURIOUS: target=freeOverload1 target=freeOverload2 +} + +// --- Overload: init overloading --- + +class MultiInit { + var value: String + + init() { // name=MultiInit.init1 + value = "default" // $ field=MultiInit.value + } + + init(int: Int) { // name=MultiInit.init2 + value = "int" // $ field=MultiInit.value + } + + init(str: String) { // name=MultiInit.init3 + value = str // $ type=str:String $ field=MultiInit.value + } + + init(x: Int, y: Int) { // name=MultiInit.init4 + value = "pair" // $ field=MultiInit.value + } + + func getValue() -> String { + return value // $ type=value:String $ field=MultiInit.value + } +} + +func testInitOverloading() { + let m1 = MultiInit() // $ type=m1:MultiInit target=MultiInit.init1 $ SPURIOUS: target=MultiInit.init2 target=MultiInit.init3 target=MultiInit.init4 + let m2 = MultiInit(int: 5) // $ type=m2:MultiInit target=MultiInit.init2 $ SPURIOUS: target=MultiInit.init1 target=MultiInit.init3 target=MultiInit.init4 + let m3 = MultiInit(str: "x") // $ type=m3:MultiInit target=MultiInit.init3 $ SPURIOUS: target=MultiInit.init1 target=MultiInit.init2 target=MultiInit.init4 + let m4 = MultiInit(x: 1, y: 2) // $ type=m4:MultiInit target=MultiInit.init4 $ SPURIOUS: target=MultiInit.init1 target=MultiInit.init2 target=MultiInit.init3 + let v = m1.getValue() // $ type=v:String target=MultiInit.getValue +} + +// --- Overload: static vs instance method --- + +class StaticVsInstance { + func action() -> String { // name=StaticVsInstance.action1 + return "instance" + } + + static func action() -> String { // name=StaticVsInstance.action2 + return "static" + } + + init() {} +} + +func testStaticVsInstance() { + let o = StaticVsInstance() // $ target=StaticVsInstance.init + let r1 = o.action() // $ type=r1:String target=StaticVsInstance.action1 + let r2 = StaticVsInstance.action() // $ type=r2:String target=StaticVsInstance.action2 +} + +// --- Overload: protocol extension default vs concrete implementation --- + +protocol Describable { + func describe() -> String // name=Describable.describe +} + +extension Describable { + func describe() -> String { // name=Describable.describe_default + return "default" + } + + func extra() -> String { + return "extra" + } +} + +class DescribableImpl: Describable { + init() {} // name=DescribableImpl.init + + func describe() -> String { // name=DescribableImpl.describe + return "concrete" + } +} + +func testProtocolExtensionOverload() { + let d = DescribableImpl() // $ target=DescribableImpl.init + let r1 = d.describe() // $ type=r1:String target=DescribableImpl.describe + let r2 = d.extra() // $ type=r2:String target=Describable.extra +} + +// --- Overload: subclass override resolution --- + +class Base { + init() {} + + func action() -> String { + return "base" + } + + func baseOnly() -> String { + return "baseOnly" + } +} + +class Sub: Base { + override init() { + super.init() // $ target=Base.init + } + + override func action() -> String { + return "sub" + } + + func subOnly() -> String { + return "subOnly" + } +} + +class SubSub: Sub { + override init() { + super.init() // $ target=Sub.init + } + + override func action() -> String { + return "subsub" + } +} + +func testOverrideResolution() { + let b = Base() // $ target=Base.init + let rb = b.action() // $ type=rb:String target=Base.action + + let s = Sub() // $ target=Sub.init + let rs = s.action() // $ type=rs:String target=Sub.action + let rbo = s.baseOnly() // $ type=rbo:String target=Base.baseOnly + let rso = s.subOnly() // $ type=rso:String target=Sub.subOnly + + let ss = SubSub() // $ target=SubSub.init + let rss = ss.action() // $ type=rss:String target=SubSub.action + let rbo2 = ss.baseOnly() // $ type=rbo2:String target=Base.baseOnly + let rso2 = ss.subOnly() // $ type=rso2:String target=Sub.subOnly +} + +// --- Overload: by external vs internal parameter names --- + +class LabelVariants { + public init() {} + + func send(to target: String) -> String { // name=LabelVariants.send1 + return target // $ type=target:String + } + + func send(from source: String) -> String { // name=LabelVariants.send2 + return source // $ type=source:String + } + + func send(to target: String, from source: String) -> String { // name=LabelVariants.send3 + return target + source + } +} + +func testLabelVariants() { + let o = LabelVariants() // $ target=LabelVariants.init + let r1 = o.send(to: "x") // $ type=r1:String target=LabelVariants.send1 $ SPURIOUS: target=LabelVariants.send2 target=LabelVariants.send3 + let r2 = o.send(from: "y") // $ type=r2:String target=LabelVariants.send2 $ SPURIOUS: target=LabelVariants.send1 target=LabelVariants.send3 + let r3 = o.send(to: "x", from: "y") // $ type=r3:String target=LabelVariants.send3 $ SPURIOUS: target=LabelVariants.send1 target=LabelVariants.send2 +} + +// --- Overload: generic function with different constraint satisfaction --- + +protocol Numeric2: Equatable { + static func zero() -> Self +} + +extension Int: Numeric2 { + static func zero() -> Int { return 0 } +} + +extension Double: Numeric2 { + static func zero() -> Double { return 0.0 } +} + +func constrainedId(_ x: T) -> T { // name=constrainedId1 + return x +} + +func constrainedId(_ x: T) -> T { // name=constrainedId2 + return x +} + +func testConstrainedOverload() { + let r1 = constrainedId(42) // $ type=r1:Int target=constrainedId1 $ SPURIOUS: target=constrainedId2 + let r2 = constrainedId("hello") // $ type=r2:String target=constrainedId2 $ SPURIOUS: target=constrainedId1 +} + +// --- Overload: methods on generic type specialized differently --- + +class Box { + var item: T + + init(_ item: T) { + self.item = item // $ type=item:T field=Box.item + } + + func get() -> T { + return item // $ type=item:T field=Box.item + } + + func replace(_ newItem: T) { + item = newItem // $ type=newItem:T field=Box.item + } +} + +func testGenericMethodResolution() { + let intBox = Box(10) // $ type=intBox@Box:Int target=Box.init + let strBox = Box("hi") // $ type=strBox@Box:String target=Box.init + let v1 = intBox.get() // $ type=v1:Int target=Box.get + let v2 = strBox.get() // $ type=v2:String target=Box.get + intBox.replace(20) // $ target=Box.replace + strBox.replace("bye") // $ target=Box.replace +} + +// --- Overload: convenience init vs designated init --- + +class Widget { + var name: String + var size: Int + + init(name: String, size: Int) { // name=Widget.init1 + self.name = name // $ type=name:String field=Widget.name + self.size = size // $ type=size:Int field=Widget.size + } + + convenience init(name: String) { // name=Widget.init2 + self.init(name: name, size: 1) // $ target=Widget.init1 $ SPURIOUS: target=Widget.init2 target=Widget.init3 + } + + convenience init(size: Int) { // name=Widget.init3 + self.init(name: "default", size: size) // $ target=Widget.init1 $ SPURIOUS: target=Widget.init2 target=Widget.init3 + } +} + +func testConvenienceInit() { + let w1 = Widget(name: "a", size: 5) // $ type=w1:Widget target=Widget.init1 $ SPURIOUS: target=Widget.init2 target=Widget.init3 + let w2 = Widget(name: "b") // $ type=w2:Widget target=Widget.init2 $ SPURIOUS: target=Widget.init1 target=Widget.init3 + let w3 = Widget(size: 10) // $ type=w3:Widget target=Widget.init3 $ SPURIOUS: target=Widget.init1 target=Widget.init2 +} + +// --- Overload: methods with closure parameters of different signatures --- + +class Processor { + init() {} + + func apply(_ f: (Int) -> Int) -> Int { // name=Processor.apply1 + return f(0) // $ target=Function.invoke + } + + func apply(_ f: (String) -> String) -> String { // name=Processor.apply2 + return f("") // $ target=Function.invoke + } + + func apply(_ f: (Int, Int) -> Int) -> Int { // name=Processor.apply3 + return f(0, 0) // $ target=Function.invoke + } +} + +func testClosureOverload() { + let p = Processor() // $ target=Processor.init + let r1 = p.apply({ x in x + 1 }) // $ type=r1:Int target=Processor.apply1 $ SPURIOUS: target=Processor.apply2 target=Processor.apply3 + let r2 = p.apply({ s in s + "!" }) // $ type=r2:String target=Processor.apply2 $ SPURIOUS: target=Processor.apply1 target=Processor.apply3 + let r3 = p.apply({ x, y in x + y }) // $ type=r3:Int target=Processor.apply3 $ SPURIOUS: target=Processor.apply1 target=Processor.apply2 +} + +// --- Overload: subscript-like method overloading --- + +class MultiSubscript { + var data: [Int] = [1, 2, 3] + var dict: [String: Int] = ["a": 1] + + init() {} + + func get(_ index: Int) -> Int { // name=MultiSubscript.get1 + return data[index] // $ field=MultiSubscript.data + } + + func get(_ key: String) -> Int { // name=MultiSubscript.get2 + return dict[key] ?? 0 // $ field=MultiSubscript.dict + } +} + +func testMethodSubscriptLike() { + let ms = MultiSubscript() // $ target=MultiSubscript.init + let r1 = ms.get(0) // $ type=r1:Int target=MultiSubscript.get1 $ SPURIOUS: target=MultiSubscript.get2 + let r2 = ms.get("a") // $ type=r2:Int target=MultiSubscript.get2 $ SPURIOUS: target=MultiSubscript.get1 +} diff --git a/unified/ql/test/library-tests/type-inference/pattern_matching.swift b/unified/ql/test/library-tests/type-inference/pattern_matching.swift new file mode 100644 index 000000000000..55ccfd750b16 --- /dev/null +++ b/unified/ql/test/library-tests/type-inference/pattern_matching.swift @@ -0,0 +1,33 @@ +func testSimplePattern(_ pair: (Int, String)) { + let (number, text) = pair + _ = number // $ type=number:Int + _ = text // $ type=text:String +} + +enum PatternMatch { + case novalue + case value(T) + case nested((T, (Int, String?))) +} + +func testComplexPattern(_ input: PatternMatch) { + switch input { + case .novalue: + break + case .value(let value): + _ = value // $ type=value:T + case .nested((let value, (let count, let label?))): + _ = value // $ type=value:T + _ = count // $ type=count:Int + _ = label // $ type=label:String + case .nested((let value, (let count, nil))): + _ = value // $ type=value:T + _ = count // $ type=count:Int + } +} + +func createValue() -> PatternMatch { + var x = PatternMatch.value(42) // $ type=x@PatternMatch:Int target=PatternMatch.value + var y = PatternMatch.novalue // $ type=y@PatternMatch:String field=PatternMatch.novalue + return PatternMatch.novalue // $ type=.novalue@PatternMatch:Bool field=PatternMatch.novalue +} diff --git a/unified/ql/test/library-tests/type-inference/protocols.swift b/unified/ql/test/library-tests/type-inference/protocols.swift new file mode 100644 index 000000000000..2e1035bca0ea --- /dev/null +++ b/unified/ql/test/library-tests/type-inference/protocols.swift @@ -0,0 +1,104 @@ +// --- Protocols and protocol conformance --- + +protocol Shape { + func area() -> Double +} + +struct Circle: Shape { + var radius: Double + + init(radius: Double) { + self.radius = radius // $ type=radius:Double + } + + func area() -> Double { + return 3.14159 * radius * radius // $ type=.radius:Double + } +} + +struct Rectangle: Shape { + var width: Double + var height: Double + + init(width: Double, height: Double) { + self.width = width // $ type=width:Double + self.height = height // $ type=height:Double + } + + func area() -> Double { + return width * height // $ type=.width:Double + } +} + +func testProtocol() { + let c = Circle(radius: 5.0) // $ type=c:Circle target=Circle.init + let a1 = c.area() // $ type=a1:Double target=Circle.area + + let r = Rectangle(width: 3.0, height: 4.0) // $ type=r:Rectangle target=Rectangle.init + let a2 = r.area() // $ type=a2:Double target=Rectangle.area +} + +// --- Protocol with associated types --- + +protocol Container { + associatedtype Item + func getItem() -> Item + func count() -> Int +} + +struct IntContainer: Container { + typealias Item = Int + var items: [Int] + + init(items: [Int]) { + self.items = items + } + + func getItem() -> Int { + return items[0] + } + + func count() -> Int { + return items.count + } +} + +func testAssociatedTypes() { + let ic = IntContainer(items: [1, 2, 3]) // $ type=ic:IntContainer target=IntContainer.init + let item = ic.getItem() // $ type=item:Int target=IntContainer.getItem + let cnt = ic.count() // $ type=cnt:Int target=IntContainer.count +} + +// --- Multiple protocol conformance --- + +protocol Printable { + func display() -> String +} + +protocol Identifiable { + func id() -> Int +} + +class Entity: Printable, Identifiable { + var name: String + var entityId: Int + + init(name: String, entityId: Int) { + self.name = name // $ type=name:String + self.entityId = entityId // $ type=entityId:Int + } + + func display() -> String { + return name // $ type=.name:String + } + + func id() -> Int { + return entityId // $ type=.entityId:Int + } +} + +func testMultipleProtocols() { + let e = Entity(name: "test", entityId: 42) // $ type=e:Entity target=Entity.init + let d = e.display() // $ type=d:String target=Entity.display + let eid = e.id() // $ type=eid:Int target=Entity.id +} diff --git a/unified/ql/test/library-tests/type-inference/type-inference.expected b/unified/ql/test/library-tests/type-inference/type-inference.expected new file mode 100644 index 000000000000..af3b09923ab6 --- /dev/null +++ b/unified/ql/test/library-tests/type-inference/type-inference.expected @@ -0,0 +1,2555 @@ +inferCertainType +| basics.swift:1:5:1:16 | topLevelDecl | | {EXTERNAL LOCATION} | Int | +| basics.swift:3:1:3:12 | topLevelDecl | | {EXTERNAL LOCATION} | Int | +| basics.swift:6:7:6:11 | myInt | | {EXTERNAL LOCATION} | Int | +| basics.swift:7:8:7:8 | n | | {EXTERNAL LOCATION} | Int | +| basics.swift:8:5:8:9 | myInt | | {EXTERNAL LOCATION} | Int | +| basics.swift:8:13:8:13 | n | | {EXTERNAL LOCATION} | Int | +| basics.swift:12:12:12:16 | myInt | | {EXTERNAL LOCATION} | Int | +| basics.swift:28:7:28:11 | value | | basics.swift:27:15:27:15 | T | +| basics.swift:29:8:29:8 | v | | basics.swift:27:15:27:15 | T | +| basics.swift:30:5:30:9 | value | | basics.swift:27:15:27:15 | T | +| basics.swift:30:13:30:13 | v | | basics.swift:27:15:27:15 | T | +| basics.swift:34:12:34:16 | value | | basics.swift:27:15:27:15 | T | +| classes.swift:4:22:4:22 | x | | {EXTERNAL LOCATION} | Int | +| classes.swift:5:12:5:12 | x | | {EXTERNAL LOCATION} | Int | +| classes.swift:5:16:5:16 | x | | {EXTERNAL LOCATION} | Int | +| classes.swift:8:19:8:19 | x | | {EXTERNAL LOCATION} | Int | +| classes.swift:9:12:9:12 | x | | {EXTERNAL LOCATION} | Int | +| classes.swift:9:16:9:16 | x | | {EXTERNAL LOCATION} | Int | +| classes.swift:9:20:9:20 | x | | {EXTERNAL LOCATION} | Int | +| classes.swift:21:18:21:18 | x | | {EXTERNAL LOCATION} | Int | +| classes.swift:22:12:22:12 | x | | {EXTERNAL LOCATION} | Int | +| classes.swift:25:18:25:18 | s | | {EXTERNAL LOCATION} | String | +| classes.swift:26:12:26:12 | s | | {EXTERNAL LOCATION} | String | +| classes.swift:39:7:39:10 | data | | {EXTERNAL LOCATION} | Array | +| classes.swift:39:7:39:10 | data | Element | {EXTERNAL LOCATION} | Array | +| classes.swift:39:7:39:10 | data | Element.Element | {EXTERNAL LOCATION} | Int | +| classes.swift:41:8:41:11 | data | | {EXTERNAL LOCATION} | Array | +| classes.swift:41:8:41:11 | data | Element | {EXTERNAL LOCATION} | Array | +| classes.swift:41:8:41:11 | data | Element.Element | {EXTERNAL LOCATION} | Int | +| classes.swift:42:5:42:8 | self | | classes.swift:38:1:48:1 | Matrix | +| classes.swift:42:17:42:20 | data | | {EXTERNAL LOCATION} | Array | +| classes.swift:42:17:42:20 | data | Element | {EXTERNAL LOCATION} | Array | +| classes.swift:42:17:42:20 | data | Element.Element | {EXTERNAL LOCATION} | Int | +| classes.swift:46:12:46:15 | data | | {EXTERNAL LOCATION} | Array | +| classes.swift:46:12:46:15 | data | Element | {EXTERNAL LOCATION} | Array | +| classes.swift:46:12:46:15 | data | Element.Element | {EXTERNAL LOCATION} | Int | +| classes.swift:51:24:51:39 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | +| classes.swift:51:25:51:30 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | +| classes.swift:51:33:51:38 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | +| classes.swift:59:9:59:13 | value | | {EXTERNAL LOCATION} | Int | +| classes.swift:61:10:61:14 | value | | {EXTERNAL LOCATION} | Int | +| classes.swift:62:7:62:10 | self | | classes.swift:58:3:68:3 | Inner | +| classes.swift:62:20:62:24 | value | | {EXTERNAL LOCATION} | Int | +| classes.swift:66:14:66:17 | self | | classes.swift:58:3:68:3 | Inner | +| classes.swift:79:7:79:11 | value | | {EXTERNAL LOCATION} | Int | +| classes.swift:83:14:83:14 | v | | {EXTERNAL LOCATION} | Int | +| classes.swift:84:5:84:9 | value | | {EXTERNAL LOCATION} | Int | +| classes.swift:84:13:84:13 | v | | {EXTERNAL LOCATION} | Int | +| classes.swift:85:12:85:15 | self | | classes.swift:78:1:96:1 | Builder | +| classes.swift:88:14:88:14 | v | | {EXTERNAL LOCATION} | Int | +| classes.swift:89:5:89:9 | value | | {EXTERNAL LOCATION} | Int | +| classes.swift:89:14:89:14 | v | | {EXTERNAL LOCATION} | Int | +| classes.swift:90:12:90:15 | self | | classes.swift:78:1:96:1 | Builder | +| classes.swift:94:12:94:16 | value | | {EXTERNAL LOCATION} | Int | +| classes.swift:108:14:108:20 | retries | | {EXTERNAL LOCATION} | Int | +| classes.swift:108:32:108:38 | timeout | | {EXTERNAL LOCATION} | Double | +| classes.swift:109:12:109:18 | retries | | {EXTERNAL LOCATION} | Int | +| classes.swift:123:7:123:13 | celsius | | {EXTERNAL LOCATION} | Double | +| classes.swift:125:8:125:14 | celsius | | {EXTERNAL LOCATION} | Double | +| classes.swift:126:5:126:8 | self | | classes.swift:122:1:136:1 | Temperature | +| classes.swift:126:20:126:26 | celsius | | {EXTERNAL LOCATION} | Double | +| classes.swift:130:12:130:18 | celsius | | {EXTERNAL LOCATION} | Double | +| classes.swift:134:12:134:18 | celsius | | {EXTERNAL LOCATION} | Double | +| classes.swift:190:7:190:11 | count | | {EXTERNAL LOCATION} | Int | +| classes.swift:193:5:193:9 | count | | {EXTERNAL LOCATION} | Int | +| classes.swift:197:12:197:16 | count | | {EXTERNAL LOCATION} | Int | +| closures.swift:2:9:2:14 | addOne | | {EXTERNAL LOCATION} | Function | +| closures.swift:2:9:2:14 | addOne | Args | {EXTERNAL LOCATION} | Tuple1 | +| closures.swift:2:18:4:5 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| closures.swift:2:18:4:5 | FunctionExpr | Args | {EXTERNAL LOCATION} | Tuple1 | +| closures.swift:5:18:5:23 | addOne | | {EXTERNAL LOCATION} | Function | +| closures.swift:5:18:5:23 | addOne | Args | {EXTERNAL LOCATION} | Tuple1 | +| closures.swift:9:28:9:35 | callback | | {EXTERNAL LOCATION} | Function | +| closures.swift:9:28:9:35 | callback | Args | {EXTERNAL LOCATION} | Tuple1 | +| closures.swift:9:28:9:35 | callback | Args.T0 | {EXTERNAL LOCATION} | Int | +| closures.swift:9:28:9:35 | callback | Return | {EXTERNAL LOCATION} | String | +| closures.swift:9:38:9:52 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| closures.swift:9:38:9:52 | FunctionExpr | Return | {EXTERNAL LOCATION} | String | +| closures.swift:10:5:10:12 | callback | | {EXTERNAL LOCATION} | Function | +| closures.swift:10:5:10:12 | callback | Args | {EXTERNAL LOCATION} | Tuple1 | +| closures.swift:10:5:10:12 | callback | Args.T0 | {EXTERNAL LOCATION} | Int | +| closures.swift:10:5:10:12 | callback | Return | {EXTERNAL LOCATION} | String | +| closures.swift:13:36:13:43 | callback | | {EXTERNAL LOCATION} | Function | +| closures.swift:13:36:13:43 | callback | Args | {EXTERNAL LOCATION} | Tuple1 | +| closures.swift:13:36:13:43 | callback | Args.T0 | closures.swift:13:30:13:31 | T1 | +| closures.swift:13:46:13:57 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| closures.swift:13:62:13:64 | arg | | closures.swift:13:30:13:31 | T1 | +| closures.swift:14:5:14:12 | callback | | {EXTERNAL LOCATION} | Function | +| closures.swift:14:5:14:12 | callback | Args | {EXTERNAL LOCATION} | Tuple1 | +| closures.swift:14:5:14:12 | callback | Args.T0 | closures.swift:13:30:13:31 | T1 | +| closures.swift:14:14:14:16 | arg | | closures.swift:13:30:13:31 | T1 | +| closures.swift:15:12:15:14 | arg | | closures.swift:13:30:13:31 | T1 | +| closures.swift:19:38:21:5 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| closures.swift:19:38:21:5 | FunctionExpr | Args | {EXTERNAL LOCATION} | Tuple1 | +| closures.swift:25:9:27:9 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| closures.swift:25:9:27:9 | FunctionExpr | Args | {EXTERNAL LOCATION} | Tuple1 | +| closures.swift:32:9:32:9 | f | | {EXTERNAL LOCATION} | Function | +| closures.swift:32:9:32:9 | f | Args | {EXTERNAL LOCATION} | Tuple1 | +| closures.swift:32:9:32:9 | f | Args.T0 | {EXTERNAL LOCATION} | Int | +| closures.swift:32:9:32:9 | f | Return | {EXTERNAL LOCATION} | Int | +| closures.swift:32:12:32:23 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| closures.swift:32:12:32:23 | FunctionExpr | Return | {EXTERNAL LOCATION} | Int | +| closures.swift:34:10:34:10 | f | | {EXTERNAL LOCATION} | Function | +| closures.swift:34:10:34:10 | f | Args | {EXTERNAL LOCATION} | Tuple1 | +| closures.swift:34:10:34:10 | f | Args.T0 | {EXTERNAL LOCATION} | Int | +| closures.swift:34:10:34:10 | f | Return | {EXTERNAL LOCATION} | Int | +| closures.swift:34:14:34:18 | value | | {EXTERNAL LOCATION} | Int | +| closures.swift:38:9:38:10 | f2 | | {EXTERNAL LOCATION} | Function | +| closures.swift:38:9:38:10 | f2 | Args | {EXTERNAL LOCATION} | Tuple1 | +| closures.swift:38:9:38:10 | f2 | Args.T0 | {EXTERNAL LOCATION} | Int | +| closures.swift:38:9:38:10 | f2 | Return | {EXTERNAL LOCATION} | Int | +| closures.swift:38:13:38:24 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| closures.swift:38:13:38:24 | FunctionExpr | Return | {EXTERNAL LOCATION} | Int | +| closures.swift:41:9:41:12 | self | | closures.swift:31:1:49:1 | C | +| closures.swift:42:9:42:12 | self | | closures.swift:31:1:49:1 | C | +| closures.swift:45:24:45:28 | value | | {EXTERNAL LOCATION} | Int | +| closures.swift:46:9:46:12 | self | | closures.swift:31:1:49:1 | C | +| closures.swift:46:16:46:20 | value | | {EXTERNAL LOCATION} | Int | +| closures.swift:47:16:47:19 | self | | closures.swift:31:1:49:1 | C | +| closures.swift:47:24:47:28 | value | | {EXTERNAL LOCATION} | Int | +| context.swift:2:7:2:13 | numbers | | {EXTERNAL LOCATION} | Array | +| context.swift:2:17:2:25 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | +| context.swift:4:17:4:23 | numbers | | {EXTERNAL LOCATION} | Array | +| context.swift:4:29:6:3 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| context.swift:4:29:6:3 | FunctionExpr | Args | {EXTERNAL LOCATION} | Tuple1 | +| fields.swift:2:7:2:20 | inheritedField | | {EXTERNAL LOCATION} | Int | +| fields.swift:6:7:6:17 | storedField | | {EXTERNAL LOCATION} | String | +| fields.swift:7:7:7:18 | genericField | | fields.swift:5:22:5:22 | T | +| fields.swift:9:8:9:19 | genericField | | fields.swift:5:22:5:22 | T | +| fields.swift:10:5:10:8 | self | | fields.swift:5:1:20:1 | FieldContainer | +| fields.swift:10:5:10:8 | self | T | fields.swift:5:22:5:22 | T | +| fields.swift:10:25:10:36 | genericField | | fields.swift:5:22:5:22 | T | +| fields.swift:14:12:14:22 | storedField | | {EXTERNAL LOCATION} | String | +| fields.swift:18:12:18:15 | self | | fields.swift:5:1:20:1 | FieldContainer | +| fields.swift:18:12:18:15 | self | T | fields.swift:5:22:5:22 | T | +| fields.swift:23:14:23:24 | staticField | | {EXTERNAL LOCATION} | Bool | +| fields.swift:27:7:27:11 | value | | {EXTERNAL LOCATION} | Double | +| fields.swift:31:7:31:12 | nested | | fields.swift:26:1:28:1 | NestedField | +| generics.swift:3:20:3:20 | x | | generics.swift:3:15:3:15 | T | +| generics.swift:4:10:4:10 | x | | generics.swift:3:15:3:15 | T | +| generics.swift:7:23:7:23 | a | | generics.swift:7:15:7:16 | A | +| generics.swift:7:31:7:31 | b | | generics.swift:7:18:7:18 | B | +| generics.swift:8:11:8:11 | a | | generics.swift:7:15:7:16 | A | +| generics.swift:8:14:8:14 | b | | generics.swift:7:18:7:18 | B | +| generics.swift:20:7:20:11 | first | | generics.swift:19:13:19:14 | A | +| generics.swift:21:7:21:12 | second | | generics.swift:19:16:19:16 | B | +| generics.swift:23:8:23:12 | first | | generics.swift:19:13:19:14 | A | +| generics.swift:23:18:23:23 | second | | generics.swift:19:16:19:16 | B | +| generics.swift:24:5:24:8 | self | | generics.swift:19:1:35:1 | Pair | +| generics.swift:24:5:24:8 | self | A | generics.swift:19:13:19:14 | A | +| generics.swift:24:5:24:8 | self | B | generics.swift:19:16:19:16 | B | +| generics.swift:24:18:24:22 | first | | generics.swift:19:13:19:14 | A | +| generics.swift:25:5:25:8 | self | | generics.swift:19:1:35:1 | Pair | +| generics.swift:25:5:25:8 | self | A | generics.swift:19:13:19:14 | A | +| generics.swift:25:5:25:8 | self | B | generics.swift:19:16:19:16 | B | +| generics.swift:25:19:25:24 | second | | generics.swift:19:16:19:16 | B | +| generics.swift:29:12:29:16 | first | | generics.swift:19:13:19:14 | A | +| generics.swift:33:12:33:17 | second | | generics.swift:19:16:19:16 | B | +| generics.swift:50:12:50:15 | self | | generics.swift:45:1:57:1 | Result | +| generics.swift:50:12:50:15 | self | T | generics.swift:45:13:45:13 | T | +| generics.swift:63:7:63:8 | r2 | | generics.swift:45:1:57:1 | Result | +| generics.swift:63:7:63:8 | r2 | T | {EXTERNAL LOCATION} | Int | +| generics.swift:64:12:64:13 | r2 | | generics.swift:45:1:57:1 | Result | +| generics.swift:64:12:64:13 | r2 | T | {EXTERNAL LOCATION} | Int | +| generics.swift:69:29:69:33 | value | | generics.swift:69:21:69:22 | T | +| generics.swift:69:41:69:49 | transform | | {EXTERNAL LOCATION} | Function | +| generics.swift:69:41:69:49 | transform | Args | {EXTERNAL LOCATION} | Tuple1 | +| generics.swift:69:41:69:49 | transform | Args.T0 | generics.swift:69:21:69:22 | T | +| generics.swift:69:41:69:49 | transform | Return | generics.swift:69:24:69:24 | U | +| generics.swift:69:52:69:59 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| generics.swift:69:52:69:59 | FunctionExpr | Return | generics.swift:69:24:69:24 | U | +| generics.swift:70:16:70:24 | transform | | {EXTERNAL LOCATION} | Function | +| generics.swift:70:16:70:24 | transform | Args | {EXTERNAL LOCATION} | Tuple1 | +| generics.swift:70:16:70:24 | transform | Args.T0 | generics.swift:69:21:69:22 | T | +| generics.swift:70:16:70:24 | transform | Return | generics.swift:69:24:69:24 | U | +| generics.swift:70:26:70:30 | value | | generics.swift:69:21:69:22 | T | +| generics.swift:75:34:75:47 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| generics.swift:75:34:75:47 | FunctionExpr | Args | {EXTERNAL LOCATION} | Tuple1 | +| generics.swift:78:5:80:5 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| generics.swift:78:5:80:5 | FunctionExpr | Args | {EXTERNAL LOCATION} | Tuple1 | +| generics.swift:94:7:94:11 | inner | | generics.swift:93:15:93:27 | T | +| generics.swift:96:10:96:14 | inner | | generics.swift:93:15:93:27 | T | +| generics.swift:97:5:97:8 | self | | generics.swift:93:1:113:1 | Wrapper | +| generics.swift:97:5:97:8 | self | T | generics.swift:93:15:93:27 | T | +| generics.swift:97:18:97:22 | inner | | generics.swift:93:15:93:27 | T | +| generics.swift:101:12:101:16 | inner | | generics.swift:93:15:93:27 | T | +| generics.swift:105:13:105:17 | inner | | generics.swift:93:15:93:27 | T | +| generics.swift:110:13:110:17 | inner | | generics.swift:93:15:93:27 | T | +| generics.swift:119:12:119:15 | self | | {EXTERNAL LOCATION} | Int | +| generics.swift:136:7:136:12 | value1 | | generics.swift:135:12:135:14 | T1 | +| generics.swift:137:7:137:12 | value2 | | generics.swift:135:16:135:17 | T2 | +| generics.swift:139:10:139:11 | v1 | | generics.swift:135:12:135:14 | T1 | +| generics.swift:139:20:139:21 | v2 | | generics.swift:135:16:135:17 | T2 | +| generics.swift:140:5:140:8 | self | | generics.swift:135:1:151:1 | Base | +| generics.swift:140:5:140:8 | self | T1 | generics.swift:135:12:135:14 | T1 | +| generics.swift:140:5:140:8 | self | T2 | generics.swift:135:16:135:17 | T2 | +| generics.swift:140:19:140:20 | v1 | | generics.swift:135:12:135:14 | T1 | +| generics.swift:141:5:141:8 | self | | generics.swift:135:1:151:1 | Base | +| generics.swift:141:5:141:8 | self | T1 | generics.swift:135:12:135:14 | T1 | +| generics.swift:141:5:141:8 | self | T2 | generics.swift:135:16:135:17 | T2 | +| generics.swift:141:19:141:20 | v2 | | generics.swift:135:16:135:17 | T2 | +| generics.swift:145:12:145:17 | value1 | | generics.swift:135:12:135:14 | T1 | +| generics.swift:149:12:149:17 | value2 | | generics.swift:135:16:135:17 | T2 | +| generics.swift:154:10:154:11 | v1 | | generics.swift:153:15:153:17 | T1 | +| generics.swift:154:20:154:21 | v2 | | generics.swift:153:19:153:20 | T2 | +| generics.swift:155:16:155:17 | v2 | | generics.swift:153:19:153:20 | T2 | +| generics.swift:155:20:155:21 | v1 | | generics.swift:153:15:153:17 | T1 | +| generics.swift:160:10:160:10 | v | | generics.swift:159:22:159:22 | D | +| generics.swift:161:16:161:16 | v | | generics.swift:159:22:159:22 | D | +| generics.swift:185:12:185:15 | self | | generics.swift:177:1:181:1 | MyProtocol2 | +| generics.swift:190:7:190:11 | value | | generics.swift:189:15:189:15 | T | +| generics.swift:192:10:192:14 | value | | generics.swift:189:15:189:15 | T | +| generics.swift:193:5:193:8 | self | | generics.swift:189:1:195:1 | MyClass | +| generics.swift:193:5:193:8 | self | T | generics.swift:189:15:189:15 | T | +| generics.swift:193:18:193:22 | value | | generics.swift:189:15:189:15 | T | +| generics.swift:205:32:205:32 | c | | generics.swift:205:14:205:27 | T | +| generics.swift:206:10:206:10 | c | | generics.swift:205:14:205:27 | T | +| generics.swift:209:32:209:32 | c | | generics.swift:209:14:209:27 | T | +| generics.swift:210:10:210:10 | c | | generics.swift:209:14:209:27 | T | +| generics.swift:244:65:244:69 | value | | generics.swift:244:33:244:60 | T | +| generics.swift:245:10:245:14 | value | | generics.swift:244:33:244:60 | T | +| key_paths.swift:4:7:4:7 | x | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:5:7:5:7 | y | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:7:8:7:8 | x | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:7:19:7:19 | y | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:8:5:8:8 | self | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:8:14:8:14 | x | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:9:5:9:8 | self | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:9:14:9:14 | y | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:13:13:13:13 | x | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:13:17:13:17 | x | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:13:21:13:21 | y | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:13:25:13:25 | y | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:18:7:18:11 | start | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:19:7:19:9 | end | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:21:8:21:12 | start | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:21:22:21:24 | end | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:22:5:22:8 | self | | key_paths.swift:17:1:25:1 | Line | +| key_paths.swift:22:18:22:22 | start | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:23:5:23:8 | self | | key_paths.swift:17:1:25:1 | Line | +| key_paths.swift:23:16:23:18 | end | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:59:7:59:10 | name | | {EXTERNAL LOCATION} | String | +| key_paths.swift:60:7:60:13 | address | | {EXTERNAL LOCATION} | Optional | +| key_paths.swift:60:7:60:13 | address | Wrapped | key_paths.swift:68:1:76:1 | Address | +| key_paths.swift:62:8:62:11 | name | | {EXTERNAL LOCATION} | String | +| key_paths.swift:62:22:62:28 | address | | {EXTERNAL LOCATION} | Optional | +| key_paths.swift:62:22:62:28 | address | Wrapped | key_paths.swift:68:1:76:1 | Address | +| key_paths.swift:63:5:63:8 | self | | key_paths.swift:58:1:66:1 | Person | +| key_paths.swift:63:17:63:20 | name | | {EXTERNAL LOCATION} | String | +| key_paths.swift:64:5:64:8 | self | | key_paths.swift:58:1:66:1 | Person | +| key_paths.swift:64:20:64:26 | address | | {EXTERNAL LOCATION} | Optional | +| key_paths.swift:64:20:64:26 | address | Wrapped | key_paths.swift:68:1:76:1 | Address | +| key_paths.swift:69:7:69:10 | city | | {EXTERNAL LOCATION} | String | +| key_paths.swift:70:7:70:9 | zip | | {EXTERNAL LOCATION} | String | +| key_paths.swift:72:8:72:11 | city | | {EXTERNAL LOCATION} | String | +| key_paths.swift:72:22:72:24 | zip | | {EXTERNAL LOCATION} | String | +| key_paths.swift:73:5:73:8 | self | | key_paths.swift:68:1:76:1 | Address | +| key_paths.swift:73:17:73:20 | city | | {EXTERNAL LOCATION} | String | +| key_paths.swift:74:5:74:8 | self | | key_paths.swift:68:1:76:1 | Address | +| key_paths.swift:74:16:74:18 | zip | | {EXTERNAL LOCATION} | String | +| key_paths.swift:89:7:89:10 | name | | {EXTERNAL LOCATION} | String | +| key_paths.swift:90:7:90:12 | salary | | {EXTERNAL LOCATION} | Int | +| key_paths.swift:92:8:92:11 | name | | {EXTERNAL LOCATION} | String | +| key_paths.swift:92:22:92:27 | salary | | {EXTERNAL LOCATION} | Int | +| key_paths.swift:93:5:93:8 | self | | key_paths.swift:88:1:96:1 | Employee | +| key_paths.swift:93:17:93:20 | name | | {EXTERNAL LOCATION} | String | +| key_paths.swift:94:5:94:8 | self | | key_paths.swift:88:1:96:1 | Employee | +| key_paths.swift:94:19:94:24 | salary | | {EXTERNAL LOCATION} | Int | +| key_paths.swift:98:27:98:31 | items | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:98:27:98:31 | items | Element | key_paths.swift:98:19:98:20 | T | +| key_paths.swift:98:39:98:45 | keyPath | unknown type parameter 0 | key_paths.swift:98:19:98:20 | T | +| key_paths.swift:98:39:98:45 | keyPath | unknown type parameter 1 | key_paths.swift:98:22:98:22 | V | +| key_paths.swift:99:10:99:14 | items | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:99:10:99:14 | items | Element | key_paths.swift:98:19:98:20 | T | +| key_paths.swift:99:20:99:43 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| key_paths.swift:99:34:99:40 | keyPath | unknown type parameter 0 | key_paths.swift:98:19:98:20 | T | +| key_paths.swift:99:34:99:40 | keyPath | unknown type parameter 1 | key_paths.swift:98:22:98:22 | V | +| key_paths.swift:105:7:105:15 | employees | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:105:19:105:26 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:106:28:106:36 | employees | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:108:31:108:39 | employees | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:115:7:115:10 | item | | key_paths.swift:114:19:114:19 | T | +| key_paths.swift:117:8:117:11 | item | | key_paths.swift:114:19:114:19 | T | +| key_paths.swift:118:5:118:8 | self | | key_paths.swift:114:1:120:1 | KPContainer | +| key_paths.swift:118:5:118:8 | self | T | key_paths.swift:114:19:114:19 | T | +| key_paths.swift:118:17:118:20 | item | | key_paths.swift:114:19:114:19 | T | +| key_paths.swift:155:7:155:15 | employees | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:155:19:155:26 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:156:15:156:23 | employees | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:158:18:158:26 | employees | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:165:7:165:11 | color | | {EXTERNAL LOCATION} | String | +| key_paths.swift:167:8:167:12 | color | | {EXTERNAL LOCATION} | String | +| key_paths.swift:168:5:168:8 | self | | key_paths.swift:164:1:170:1 | Shape2 | +| key_paths.swift:168:18:168:22 | color | | {EXTERNAL LOCATION} | String | +| key_paths.swift:173:7:173:12 | radius | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:175:8:175:12 | color | | {EXTERNAL LOCATION} | String | +| key_paths.swift:175:23:175:28 | radius | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:176:5:176:8 | self | | key_paths.swift:172:1:179:1 | Circle2 | +| key_paths.swift:176:19:176:24 | radius | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:177:23:177:27 | color | | {EXTERNAL LOCATION} | String | +| key_paths.swift:204:7:204:9 | arr | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:204:13:204:24 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:205:15:205:17 | arr | | {EXTERNAL LOCATION} | Array | +| overload_resolution.swift:6:17:6:17 | x | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:10:17:10:17 | x | | {EXTERNAL LOCATION} | Double | +| overload_resolution.swift:14:17:14:17 | x | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:18:17:18:17 | x | | {EXTERNAL LOCATION} | Bool | +| overload_resolution.swift:36:18:36:22 | width | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:40:18:40:23 | height | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:44:18:44:22 | width | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:44:30:44:35 | height | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:48:18:48:21 | size | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:70:18:70:18 | x | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:71:12:71:12 | x | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:74:18:74:18 | x | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:74:28:74:28 | y | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:75:12:75:12 | x | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:75:16:75:16 | y | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:78:18:78:18 | x | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:78:28:78:28 | y | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:78:38:78:38 | z | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:79:12:79:12 | x | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:79:16:79:16 | y | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:79:20:79:20 | z | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:111:7:111:8 | r1 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:112:7:112:8 | r2 | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:113:7:113:8 | r3 | | {EXTERNAL LOCATION} | Double | +| overload_resolution.swift:121:18:121:18 | x | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:125:21:125:21 | x | | overload_resolution.swift:125:16:125:16 | T | +| overload_resolution.swift:139:21:139:21 | x | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:143:21:143:21 | x | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:147:21:147:21 | x | | {EXTERNAL LOCATION} | Double | +| overload_resolution.swift:160:7:160:11 | value | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:163:5:163:9 | value | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:166:8:166:10 | int | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:167:5:167:9 | value | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:170:8:170:10 | str | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:171:5:171:9 | value | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:171:13:171:15 | str | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:174:8:174:8 | x | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:174:16:174:16 | y | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:175:5:175:9 | value | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:179:12:179:16 | value | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:299:16:299:21 | target | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:300:12:300:17 | target | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:303:18:303:23 | source | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:304:12:304:17 | source | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:307:16:307:21 | target | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:307:37:307:42 | source | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:308:12:308:17 | target | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:308:21:308:26 | source | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:333:35:333:35 | x | | overload_resolution.swift:333:20:333:30 | T | +| overload_resolution.swift:334:10:334:10 | x | | overload_resolution.swift:333:20:333:30 | T | +| overload_resolution.swift:337:36:337:36 | x | | overload_resolution.swift:337:20:337:31 | T | +| overload_resolution.swift:338:10:338:10 | x | | overload_resolution.swift:337:20:337:31 | T | +| overload_resolution.swift:349:7:349:10 | item | | overload_resolution.swift:348:11:348:11 | T | +| overload_resolution.swift:351:10:351:13 | item | | overload_resolution.swift:348:11:348:11 | T | +| overload_resolution.swift:352:5:352:8 | self | | overload_resolution.swift:348:1:362:1 | Box | +| overload_resolution.swift:352:5:352:8 | self | T | overload_resolution.swift:348:11:348:11 | T | +| overload_resolution.swift:352:17:352:20 | item | | overload_resolution.swift:348:11:348:11 | T | +| overload_resolution.swift:356:12:356:15 | item | | overload_resolution.swift:348:11:348:11 | T | +| overload_resolution.swift:359:18:359:24 | newItem | | overload_resolution.swift:348:11:348:11 | T | +| overload_resolution.swift:360:5:360:8 | item | | overload_resolution.swift:348:11:348:11 | T | +| overload_resolution.swift:360:12:360:18 | newItem | | overload_resolution.swift:348:11:348:11 | T | +| overload_resolution.swift:376:7:376:10 | name | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:377:7:377:10 | size | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:379:8:379:11 | name | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:379:22:379:25 | size | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:380:5:380:8 | self | | overload_resolution.swift:375:1:391:1 | Widget | +| overload_resolution.swift:380:17:380:20 | name | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:381:5:381:8 | self | | overload_resolution.swift:375:1:391:1 | Widget | +| overload_resolution.swift:381:17:381:20 | size | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:384:20:384:23 | name | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:385:5:385:8 | self | | overload_resolution.swift:375:1:391:1 | Widget | +| overload_resolution.swift:385:21:385:24 | name | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:388:20:388:23 | size | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:389:5:389:8 | self | | overload_resolution.swift:375:1:391:1 | Widget | +| overload_resolution.swift:389:38:389:41 | size | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:404:16:404:16 | f | | {EXTERNAL LOCATION} | Function | +| overload_resolution.swift:404:16:404:16 | f | Args | {EXTERNAL LOCATION} | Tuple1 | +| overload_resolution.swift:404:16:404:16 | f | Args.T0 | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:404:16:404:16 | f | Return | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:404:19:404:30 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| overload_resolution.swift:404:19:404:30 | FunctionExpr | Return | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:405:12:405:12 | f | | {EXTERNAL LOCATION} | Function | +| overload_resolution.swift:405:12:405:12 | f | Args | {EXTERNAL LOCATION} | Tuple1 | +| overload_resolution.swift:405:12:405:12 | f | Args.T0 | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:405:12:405:12 | f | Return | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:408:16:408:16 | f | | {EXTERNAL LOCATION} | Function | +| overload_resolution.swift:408:16:408:16 | f | Args | {EXTERNAL LOCATION} | Tuple1 | +| overload_resolution.swift:408:16:408:16 | f | Args.T0 | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:408:16:408:16 | f | Return | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:408:19:408:36 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| overload_resolution.swift:408:19:408:36 | FunctionExpr | Return | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:409:12:409:12 | f | | {EXTERNAL LOCATION} | Function | +| overload_resolution.swift:409:12:409:12 | f | Args | {EXTERNAL LOCATION} | Tuple1 | +| overload_resolution.swift:409:12:409:12 | f | Args.T0 | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:409:12:409:12 | f | Return | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:412:16:412:16 | f | | {EXTERNAL LOCATION} | Function | +| overload_resolution.swift:412:16:412:16 | f | Args | {EXTERNAL LOCATION} | Tuple2 | +| overload_resolution.swift:412:16:412:16 | f | Args.T0 | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:412:16:412:16 | f | Args.T1 | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:412:16:412:16 | f | Return | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:412:19:412:35 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| overload_resolution.swift:412:19:412:35 | FunctionExpr | Return | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:413:12:413:12 | f | | {EXTERNAL LOCATION} | Function | +| overload_resolution.swift:413:12:413:12 | f | Args | {EXTERNAL LOCATION} | Tuple2 | +| overload_resolution.swift:413:12:413:12 | f | Args.T0 | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:413:12:413:12 | f | Args.T1 | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:413:12:413:12 | f | Return | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:419:20:419:33 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| overload_resolution.swift:419:20:419:33 | FunctionExpr | Args | {EXTERNAL LOCATION} | Tuple1 | +| overload_resolution.swift:420:20:420:35 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| overload_resolution.swift:420:20:420:35 | FunctionExpr | Args | {EXTERNAL LOCATION} | Tuple1 | +| overload_resolution.swift:421:20:421:36 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| overload_resolution.swift:427:7:427:10 | data | | {EXTERNAL LOCATION} | Array | +| overload_resolution.swift:427:7:427:10 | data | Element | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:427:21:427:29 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | +| overload_resolution.swift:428:7:428:10 | dict | | {EXTERNAL LOCATION} | Dictionary | +| overload_resolution.swift:428:7:428:10 | dict | Key | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:428:7:428:10 | dict | Value | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:432:14:432:18 | index | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:433:12:433:15 | data | | {EXTERNAL LOCATION} | Array | +| overload_resolution.swift:433:12:433:15 | data | Element | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:433:17:433:21 | index | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:436:14:436:16 | key | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:437:12:437:15 | dict | | {EXTERNAL LOCATION} | Dictionary | +| overload_resolution.swift:437:12:437:15 | dict | Key | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:437:12:437:15 | dict | Value | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:437:17:437:19 | key | | {EXTERNAL LOCATION} | String | +| pattern_matching.swift:1:26:1:29 | pair | | {EXTERNAL LOCATION} | Tuple2 | +| pattern_matching.swift:1:26:1:29 | pair | T0 | {EXTERNAL LOCATION} | Int | +| pattern_matching.swift:1:26:1:29 | pair | T1 | {EXTERNAL LOCATION} | String | +| pattern_matching.swift:2:7:2:20 | TupleExpr | | {EXTERNAL LOCATION} | Tuple2 | +| pattern_matching.swift:2:7:2:20 | TupleExpr | T0 | {EXTERNAL LOCATION} | Int | +| pattern_matching.swift:2:7:2:20 | TupleExpr | T1 | {EXTERNAL LOCATION} | String | +| pattern_matching.swift:2:24:2:27 | pair | | {EXTERNAL LOCATION} | Tuple2 | +| pattern_matching.swift:2:24:2:27 | pair | T0 | {EXTERNAL LOCATION} | Int | +| pattern_matching.swift:2:24:2:27 | pair | T1 | {EXTERNAL LOCATION} | String | +| pattern_matching.swift:8:8:8:14 | novalue | | pattern_matching.swift:7:1:11:1 | PatternMatch | +| pattern_matching.swift:8:8:8:14 | novalue | T | pattern_matching.swift:7:19:7:19 | T | +| pattern_matching.swift:13:30:13:34 | input | | pattern_matching.swift:7:1:11:1 | PatternMatch | +| pattern_matching.swift:13:30:13:34 | input | T | pattern_matching.swift:13:25:13:25 | T | +| pattern_matching.swift:14:10:14:14 | input | | pattern_matching.swift:7:1:11:1 | PatternMatch | +| pattern_matching.swift:14:10:14:14 | input | T | pattern_matching.swift:13:25:13:25 | T | +| protocols.swift:8:7:8:12 | radius | | {EXTERNAL LOCATION} | Double | +| protocols.swift:10:8:10:13 | radius | | {EXTERNAL LOCATION} | Double | +| protocols.swift:11:5:11:8 | self | | protocols.swift:7:1:17:1 | Circle | +| protocols.swift:11:19:11:24 | radius | | {EXTERNAL LOCATION} | Double | +| protocols.swift:15:22:15:27 | radius | | {EXTERNAL LOCATION} | Double | +| protocols.swift:15:31:15:36 | radius | | {EXTERNAL LOCATION} | Double | +| protocols.swift:20:7:20:11 | width | | {EXTERNAL LOCATION} | Double | +| protocols.swift:21:7:21:12 | height | | {EXTERNAL LOCATION} | Double | +| protocols.swift:23:8:23:12 | width | | {EXTERNAL LOCATION} | Double | +| protocols.swift:23:23:23:28 | height | | {EXTERNAL LOCATION} | Double | +| protocols.swift:24:5:24:8 | self | | protocols.swift:19:1:31:1 | Rectangle | +| protocols.swift:24:18:24:22 | width | | {EXTERNAL LOCATION} | Double | +| protocols.swift:25:5:25:8 | self | | protocols.swift:19:1:31:1 | Rectangle | +| protocols.swift:25:19:25:24 | height | | {EXTERNAL LOCATION} | Double | +| protocols.swift:29:12:29:16 | width | | {EXTERNAL LOCATION} | Double | +| protocols.swift:29:20:29:25 | height | | {EXTERNAL LOCATION} | Double | +| protocols.swift:51:7:51:11 | items | | {EXTERNAL LOCATION} | Array | +| protocols.swift:51:7:51:11 | items | Element | {EXTERNAL LOCATION} | Int | +| protocols.swift:53:8:53:12 | items | | {EXTERNAL LOCATION} | Array | +| protocols.swift:53:8:53:12 | items | Element | {EXTERNAL LOCATION} | Int | +| protocols.swift:54:5:54:8 | self | | protocols.swift:49:1:64:1 | IntContainer | +| protocols.swift:54:18:54:22 | items | | {EXTERNAL LOCATION} | Array | +| protocols.swift:54:18:54:22 | items | Element | {EXTERNAL LOCATION} | Int | +| protocols.swift:58:12:58:16 | items | | {EXTERNAL LOCATION} | Array | +| protocols.swift:58:12:58:16 | items | Element | {EXTERNAL LOCATION} | Int | +| protocols.swift:62:12:62:16 | items | | {EXTERNAL LOCATION} | Array | +| protocols.swift:62:12:62:16 | items | Element | {EXTERNAL LOCATION} | Int | +| protocols.swift:67:32:67:40 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | +| protocols.swift:83:7:83:10 | name | | {EXTERNAL LOCATION} | String | +| protocols.swift:84:7:84:14 | entityId | | {EXTERNAL LOCATION} | Int | +| protocols.swift:86:8:86:11 | name | | {EXTERNAL LOCATION} | String | +| protocols.swift:86:22:86:29 | entityId | | {EXTERNAL LOCATION} | Int | +| protocols.swift:87:5:87:8 | self | | protocols.swift:82:1:98:1 | Entity | +| protocols.swift:87:17:87:20 | name | | {EXTERNAL LOCATION} | String | +| protocols.swift:88:5:88:8 | self | | protocols.swift:82:1:98:1 | Entity | +| protocols.swift:88:21:88:28 | entityId | | {EXTERNAL LOCATION} | Int | +| protocols.swift:92:12:92:15 | name | | {EXTERNAL LOCATION} | String | +| protocols.swift:96:12:96:19 | entityId | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:3:29:3:29 | a | | type_constraints.swift:3:12:3:24 | T | +| type_constraints.swift:3:37:3:37 | b | | type_constraints.swift:3:12:3:24 | T | +| type_constraints.swift:4:6:4:6 | a | | type_constraints.swift:3:12:3:24 | T | +| type_constraints.swift:4:10:4:10 | b | | type_constraints.swift:3:12:3:24 | T | +| type_constraints.swift:4:21:4:21 | a | | type_constraints.swift:3:12:3:24 | T | +| type_constraints.swift:4:39:4:39 | b | | type_constraints.swift:3:12:3:24 | T | +| type_constraints.swift:7:17:7:17 | a | | type_constraints.swift:7:12:7:12 | T | +| type_constraints.swift:7:25:7:25 | b | | type_constraints.swift:7:12:7:12 | T | +| type_constraints.swift:8:6:8:6 | a | | type_constraints.swift:7:12:7:12 | T | +| type_constraints.swift:8:10:8:10 | b | | type_constraints.swift:7:12:7:12 | T | +| type_constraints.swift:8:21:8:21 | a | | type_constraints.swift:7:12:7:12 | T | +| type_constraints.swift:8:39:8:39 | b | | type_constraints.swift:7:12:7:12 | T | +| type_constraints.swift:29:7:29:9 | tag | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:30:7:30:14 | priority | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:32:8:32:10 | tag | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:32:21:32:28 | priority | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:33:5:33:8 | self | | type_constraints.swift:28:1:44:1 | TaggedItem | +| type_constraints.swift:33:16:33:18 | tag | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:34:5:34:8 | self | | type_constraints.swift:28:1:44:1 | TaggedItem | +| type_constraints.swift:34:21:34:28 | priority | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:38:12:38:14 | tag | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:42:12:42:19 | priority | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:46:48:46:51 | item | | type_constraints.swift:46:18:46:43 | T | +| type_constraints.swift:47:10:47:13 | item | | type_constraints.swift:46:18:46:43 | T | +| type_constraints.swift:50:30:50:30 | a | | type_constraints.swift:50:25:50:25 | T | +| type_constraints.swift:50:38:50:38 | b | | type_constraints.swift:50:25:50:25 | T | +| type_constraints.swift:52:10:52:10 | a | | type_constraints.swift:50:25:50:25 | T | +| type_constraints.swift:52:15:52:15 | b | | type_constraints.swift:50:25:50:25 | T | +| type_constraints.swift:64:7:64:11 | first | | type_constraints.swift:63:18:63:31 | T | +| type_constraints.swift:65:7:65:12 | second | | type_constraints.swift:63:33:63:45 | U | +| type_constraints.swift:67:8:67:12 | first | | type_constraints.swift:63:18:63:31 | T | +| type_constraints.swift:67:18:67:23 | second | | type_constraints.swift:63:33:63:45 | U | +| type_constraints.swift:68:5:68:8 | self | | type_constraints.swift:63:1:79:1 | SortedPair | +| type_constraints.swift:68:5:68:8 | self | T | type_constraints.swift:63:18:63:31 | T | +| type_constraints.swift:68:5:68:8 | self | U | type_constraints.swift:63:33:63:45 | U | +| type_constraints.swift:68:18:68:22 | first | | type_constraints.swift:63:18:63:31 | T | +| type_constraints.swift:69:5:69:8 | self | | type_constraints.swift:63:1:79:1 | SortedPair | +| type_constraints.swift:69:5:69:8 | self | T | type_constraints.swift:63:18:63:31 | T | +| type_constraints.swift:69:5:69:8 | self | U | type_constraints.swift:63:33:63:45 | U | +| type_constraints.swift:69:19:69:24 | second | | type_constraints.swift:63:33:63:45 | U | +| type_constraints.swift:72:28:72:32 | other | | type_constraints.swift:63:18:63:31 | T | +| type_constraints.swift:73:12:73:16 | first | | type_constraints.swift:63:18:63:31 | T | +| type_constraints.swift:73:20:73:24 | other | | type_constraints.swift:63:18:63:31 | T | +| type_constraints.swift:76:29:76:33 | other | | type_constraints.swift:63:33:63:45 | U | +| type_constraints.swift:77:12:77:17 | second | | type_constraints.swift:63:33:63:45 | U | +| type_constraints.swift:77:21:77:25 | other | | type_constraints.swift:63:33:63:45 | U | +| type_constraints.swift:96:7:96:11 | items | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:96:7:96:11 | items | Element | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:98:8:98:12 | items | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:98:8:98:12 | items | Element | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:99:5:99:8 | self | | type_constraints.swift:94:1:105:1 | IntArray | +| type_constraints.swift:99:18:99:22 | items | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:99:18:99:22 | items | Element | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:103:12:103:16 | items | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:103:12:103:16 | items | Element | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:109:7:109:11 | items | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:109:7:109:11 | items | Element | {EXTERNAL LOCATION} | String | +| type_constraints.swift:111:8:111:12 | items | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:111:8:111:12 | items | Element | {EXTERNAL LOCATION} | String | +| type_constraints.swift:112:5:112:8 | self | | type_constraints.swift:107:1:118:1 | StringArray | +| type_constraints.swift:112:18:112:22 | items | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:112:18:112:22 | items | Element | {EXTERNAL LOCATION} | String | +| type_constraints.swift:116:12:116:16 | items | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:116:12:116:16 | items | Element | {EXTERNAL LOCATION} | String | +| type_constraints.swift:120:45:120:53 | container | | type_constraints.swift:120:19:120:37 | C | +| type_constraints.swift:121:10:121:18 | container | | type_constraints.swift:120:19:120:37 | C | +| type_constraints.swift:124:45:124:53 | container | | type_constraints.swift:124:19:124:37 | C | +| type_constraints.swift:125:10:125:18 | container | | type_constraints.swift:124:19:124:37 | C | +| type_constraints.swift:129:28:129:35 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:130:31:130:45 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:138:7:138:11 | speed | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:140:8:140:12 | speed | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:141:5:141:8 | self | | type_constraints.swift:137:1:147:1 | Vehicle | +| type_constraints.swift:141:18:141:22 | speed | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:150:17:150:21 | speed | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:151:23:151:27 | speed | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:164:17:164:21 | speed | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:165:23:165:27 | speed | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:177:36:177:36 | v | | type_constraints.swift:177:22:177:31 | T | +| type_constraints.swift:178:10:178:10 | v | | type_constraints.swift:177:22:177:31 | T | +| type_constraints.swift:193:18:193:20 | lhs | | type_constraints.swift:192:1:194:1 | Summable | +| type_constraints.swift:193:29:193:31 | rhs | | type_constraints.swift:192:1:194:1 | Summable | +| type_constraints.swift:201:7:201:12 | values | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:201:7:201:12 | values | Element | type_constraints.swift:200:20:200:20 | T | +| type_constraints.swift:203:8:203:13 | values | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:203:8:203:13 | values | Element | type_constraints.swift:200:20:200:20 | T | +| type_constraints.swift:204:5:204:8 | self | | type_constraints.swift:200:1:210:1 | Accumulator | +| type_constraints.swift:204:5:204:8 | self | T | type_constraints.swift:200:20:200:20 | T | +| type_constraints.swift:204:19:204:24 | values | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:204:19:204:24 | values | Element | type_constraints.swift:200:20:200:20 | T | +| type_constraints.swift:208:12:208:17 | values | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:208:12:208:17 | values | Element | type_constraints.swift:200:20:200:20 | T | +| type_constraints.swift:220:35:220:48 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| type_constraints.swift:225:36:225:44 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:236:33:236:37 | items | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:236:33:236:37 | items | Element | type_constraints.swift:236:18:236:28 | T | +| type_constraints.swift:237:12:237:16 | items | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:237:12:237:16 | items | Element | type_constraints.swift:236:18:236:28 | T | +| type_constraints.swift:237:23:237:27 | items | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:237:23:237:27 | items | Element | type_constraints.swift:236:18:236:28 | T | +| type_constraints.swift:240:44:240:44 | a | | type_constraints.swift:240:14:240:26 | A | +| type_constraints.swift:240:52:240:52 | b | | type_constraints.swift:240:28:240:39 | B | +| type_constraints.swift:247:24:247:32 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:248:24:248:38 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:254:29:254:33 | value | | type_constraints.swift:254:12:254:24 | T | +| type_constraints.swift:254:43:254:47 | lower | | type_constraints.swift:254:12:254:24 | T | +| type_constraints.swift:254:57:254:61 | upper | | type_constraints.swift:254:12:254:24 | T | +| type_constraints.swift:255:6:255:10 | value | | type_constraints.swift:254:12:254:24 | T | +| type_constraints.swift:255:14:255:18 | lower | | type_constraints.swift:254:12:254:24 | T | +| type_constraints.swift:255:29:255:33 | lower | | type_constraints.swift:254:12:254:24 | T | +| type_constraints.swift:256:6:256:10 | value | | type_constraints.swift:254:12:254:24 | T | +| type_constraints.swift:256:14:256:18 | upper | | type_constraints.swift:254:12:254:24 | T | +| type_constraints.swift:256:29:256:33 | upper | | type_constraints.swift:254:12:254:24 | T | +| type_constraints.swift:257:10:257:14 | value | | type_constraints.swift:254:12:254:24 | T | +inferType +| basics.swift:1:5:1:16 | topLevelDecl | | {EXTERNAL LOCATION} | Int | +| basics.swift:1:25:1:25 | 0 | | {EXTERNAL LOCATION} | Int | +| basics.swift:2:1:2:1 | 0 | | {EXTERNAL LOCATION} | Int | +| basics.swift:3:1:3:12 | topLevelDecl | | {EXTERNAL LOCATION} | Int | +| basics.swift:3:1:3:16 | ... + ... | | {EXTERNAL LOCATION} | Int | +| basics.swift:3:16:3:16 | 1 | | {EXTERNAL LOCATION} | Int | +| basics.swift:6:7:6:11 | myInt | | {EXTERNAL LOCATION} | Int | +| basics.swift:7:3:9:3 | Block | | {EXTERNAL LOCATION} | Int | +| basics.swift:7:8:7:8 | n | | {EXTERNAL LOCATION} | Int | +| basics.swift:8:5:8:9 | myInt | | {EXTERNAL LOCATION} | Int | +| basics.swift:8:5:8:13 | ... = ... | | {EXTERNAL LOCATION} | Int | +| basics.swift:8:13:8:13 | n | | {EXTERNAL LOCATION} | Int | +| basics.swift:11:3:13:3 | Block | | {EXTERNAL LOCATION} | Int | +| basics.swift:12:12:12:16 | myInt | | {EXTERNAL LOCATION} | Int | +| basics.swift:17:3:19:3 | Block | | basics.swift:5:1:14:1 | C | +| basics.swift:18:5:18:9 | super | | basics.swift:5:1:14:1 | C | +| basics.swift:18:5:18:20 | ... .init(...) | | basics.swift:5:1:14:1 | C | +| basics.swift:18:19:18:19 | 0 | | {EXTERNAL LOCATION} | Int | +| basics.swift:21:3:24:3 | Block | | {EXTERNAL LOCATION} | Int | +| basics.swift:22:9:22:9 | x | | {EXTERNAL LOCATION} | Int | +| basics.swift:22:13:22:22 | getMyInt(...) | | {EXTERNAL LOCATION} | Int | +| basics.swift:23:12:23:12 | x | | {EXTERNAL LOCATION} | Int | +| basics.swift:28:7:28:11 | value | | basics.swift:27:15:27:15 | T | +| basics.swift:29:3:31:3 | Block | | basics.swift:27:15:27:15 | T | +| basics.swift:29:8:29:8 | v | | basics.swift:27:15:27:15 | T | +| basics.swift:30:5:30:9 | value | | basics.swift:27:15:27:15 | T | +| basics.swift:30:5:30:13 | ... = ... | | basics.swift:27:15:27:15 | T | +| basics.swift:30:13:30:13 | v | | basics.swift:27:15:27:15 | T | +| basics.swift:33:3:35:3 | Block | | basics.swift:27:15:27:15 | T | +| basics.swift:34:12:34:16 | value | | basics.swift:27:15:27:15 | T | +| basics.swift:39:3:41:3 | Block | | basics.swift:27:1:36:1 | Generic | +| basics.swift:39:3:41:3 | Block | T | {EXTERNAL LOCATION} | Int | +| basics.swift:40:5:40:9 | super | | basics.swift:27:1:36:1 | Generic | +| basics.swift:40:5:40:9 | super | T | {EXTERNAL LOCATION} | Int | +| basics.swift:40:5:40:20 | ... .init(...) | | basics.swift:27:1:36:1 | Generic | +| basics.swift:40:5:40:20 | ... .init(...) | T | {EXTERNAL LOCATION} | Int | +| basics.swift:40:19:40:19 | 0 | | {EXTERNAL LOCATION} | Int | +| basics.swift:45:7:45:7 | g | | basics.swift:27:1:36:1 | Generic | +| basics.swift:45:7:45:7 | g | T | {EXTERNAL LOCATION} | Int | +| basics.swift:45:11:45:24 | Generic(...) | | basics.swift:27:1:36:1 | Generic | +| basics.swift:45:11:45:24 | Generic(...) | T | {EXTERNAL LOCATION} | Int | +| basics.swift:45:22:45:23 | 42 | | {EXTERNAL LOCATION} | Int | +| basics.swift:46:7:46:7 | x | | {EXTERNAL LOCATION} | Int | +| basics.swift:46:11:46:11 | g | | basics.swift:27:1:36:1 | Generic | +| basics.swift:46:11:46:11 | g | T | {EXTERNAL LOCATION} | Int | +| basics.swift:46:11:46:22 | ... .getValue(...) | | {EXTERNAL LOCATION} | Int | +| basics.swift:48:7:48:8 | gd | | basics.swift:38:1:42:1 | GenericDerived | +| basics.swift:48:12:48:27 | GenericDerived(...) | | basics.swift:38:1:42:1 | GenericDerived | +| basics.swift:49:7:49:7 | y | | {EXTERNAL LOCATION} | Int | +| basics.swift:49:11:49:12 | gd | | basics.swift:38:1:42:1 | GenericDerived | +| basics.swift:49:11:49:23 | ... .getValue(...) | | {EXTERNAL LOCATION} | Int | +| basics.swift:55:3:57:3 | Block | | {EXTERNAL LOCATION} | Int | +| basics.swift:56:12:56:16 | myInt | | {EXTERNAL LOCATION} | Int | +| basics.swift:56:12:56:20 | ... * ... | | {EXTERNAL LOCATION} | Int | +| basics.swift:56:20:56:20 | 2 | | {EXTERNAL LOCATION} | Int | +| basics.swift:61:7:61:9 | obj | | basics.swift:5:1:14:1 | C | +| basics.swift:61:13:61:20 | C(...) | | basics.swift:5:1:14:1 | C | +| basics.swift:61:18:61:19 | 10 | | {EXTERNAL LOCATION} | Int | +| basics.swift:62:7:62:7 | d | | {EXTERNAL LOCATION} | Int | +| basics.swift:62:11:62:13 | obj | | basics.swift:5:1:14:1 | C | +| basics.swift:62:11:62:23 | ... .doubled(...) | | {EXTERNAL LOCATION} | Int | +| classes.swift:4:3:6:3 | Block | | {EXTERNAL LOCATION} | Int | +| classes.swift:4:22:4:22 | x | | {EXTERNAL LOCATION} | Int | +| classes.swift:5:12:5:12 | x | | {EXTERNAL LOCATION} | Int | +| classes.swift:5:12:5:16 | ... * ... | | {EXTERNAL LOCATION} | Int | +| classes.swift:5:16:5:16 | x | | {EXTERNAL LOCATION} | Int | +| classes.swift:8:3:10:3 | Block | | {EXTERNAL LOCATION} | Int | +| classes.swift:8:19:8:19 | x | | {EXTERNAL LOCATION} | Int | +| classes.swift:9:12:9:12 | x | | {EXTERNAL LOCATION} | Int | +| classes.swift:9:12:9:16 | ... * ... | | {EXTERNAL LOCATION} | Int | +| classes.swift:9:12:9:20 | ... * ... | | {EXTERNAL LOCATION} | Int | +| classes.swift:9:16:9:16 | x | | {EXTERNAL LOCATION} | Int | +| classes.swift:9:20:9:20 | x | | {EXTERNAL LOCATION} | Int | +| classes.swift:14:7:14:7 | s | | {EXTERNAL LOCATION} | Int | +| classes.swift:14:11:14:32 | ... .square(...) | | {EXTERNAL LOCATION} | Int | +| classes.swift:14:31:14:31 | 4 | | {EXTERNAL LOCATION} | Int | +| classes.swift:15:7:15:8 | cu | | {EXTERNAL LOCATION} | Int | +| classes.swift:15:12:15:31 | ... .cube(...) | | {EXTERNAL LOCATION} | Int | +| classes.swift:15:30:15:30 | 3 | | {EXTERNAL LOCATION} | Int | +| classes.swift:21:3:23:3 | Block | | {EXTERNAL LOCATION} | Int | +| classes.swift:21:18:21:18 | x | | {EXTERNAL LOCATION} | Int | +| classes.swift:22:12:22:12 | x | | {EXTERNAL LOCATION} | Int | +| classes.swift:22:12:22:16 | ... + ... | | {EXTERNAL LOCATION} | Int | +| classes.swift:22:16:22:16 | 1 | | {EXTERNAL LOCATION} | Int | +| classes.swift:25:3:27:3 | Block | | {EXTERNAL LOCATION} | String | +| classes.swift:25:18:25:18 | s | | {EXTERNAL LOCATION} | String | +| classes.swift:26:12:26:12 | s | | {EXTERNAL LOCATION} | String | +| classes.swift:32:22:32:23 | 42 | | {EXTERNAL LOCATION} | Int | +| classes.swift:33:22:33:28 | "hello" | | {EXTERNAL LOCATION} | String | +| classes.swift:39:7:39:10 | data | | {EXTERNAL LOCATION} | Array | +| classes.swift:39:7:39:10 | data | Element | {EXTERNAL LOCATION} | Array | +| classes.swift:39:7:39:10 | data | Element.Element | {EXTERNAL LOCATION} | Int | +| classes.swift:41:3:43:3 | Block | | {EXTERNAL LOCATION} | Array | +| classes.swift:41:3:43:3 | Block | Element | {EXTERNAL LOCATION} | Array | +| classes.swift:41:3:43:3 | Block | Element.Element | {EXTERNAL LOCATION} | Int | +| classes.swift:41:8:41:11 | data | | {EXTERNAL LOCATION} | Array | +| classes.swift:41:8:41:11 | data | Element | {EXTERNAL LOCATION} | Array | +| classes.swift:41:8:41:11 | data | Element.Element | {EXTERNAL LOCATION} | Int | +| classes.swift:42:5:42:8 | self | | classes.swift:38:1:48:1 | Matrix | +| classes.swift:42:5:42:13 | ... .data | | {EXTERNAL LOCATION} | Array | +| classes.swift:42:5:42:13 | ... .data | Element | {EXTERNAL LOCATION} | Array | +| classes.swift:42:5:42:13 | ... .data | Element.Element | {EXTERNAL LOCATION} | Int | +| classes.swift:42:5:42:20 | ... = ... | | {EXTERNAL LOCATION} | Array | +| classes.swift:42:5:42:20 | ... = ... | Element | {EXTERNAL LOCATION} | Array | +| classes.swift:42:5:42:20 | ... = ... | Element.Element | {EXTERNAL LOCATION} | Int | +| classes.swift:42:17:42:20 | data | | {EXTERNAL LOCATION} | Array | +| classes.swift:42:17:42:20 | data | Element | {EXTERNAL LOCATION} | Array | +| classes.swift:42:17:42:20 | data | Element.Element | {EXTERNAL LOCATION} | Int | +| classes.swift:46:12:46:15 | data | | {EXTERNAL LOCATION} | Array | +| classes.swift:46:12:46:15 | data | Element | {EXTERNAL LOCATION} | Array | +| classes.swift:46:12:46:15 | data | Element.Element | {EXTERNAL LOCATION} | Int | +| classes.swift:51:7:51:7 | m | | classes.swift:38:1:48:1 | Matrix | +| classes.swift:51:11:51:40 | Matrix(...) | | classes.swift:38:1:48:1 | Matrix | +| classes.swift:51:24:51:39 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | +| classes.swift:51:24:51:39 | ArrayLiteral | Element | {EXTERNAL LOCATION} | Array | +| classes.swift:51:24:51:39 | ArrayLiteral | Element.Element | {EXTERNAL LOCATION} | Int | +| classes.swift:51:25:51:30 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | +| classes.swift:51:25:51:30 | ArrayLiteral | Element | {EXTERNAL LOCATION} | Int | +| classes.swift:51:26:51:26 | 1 | | {EXTERNAL LOCATION} | Int | +| classes.swift:51:29:51:29 | 2 | | {EXTERNAL LOCATION} | Int | +| classes.swift:51:33:51:38 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | +| classes.swift:51:33:51:38 | ArrayLiteral | Element | {EXTERNAL LOCATION} | Int | +| classes.swift:51:34:51:34 | 3 | | {EXTERNAL LOCATION} | Int | +| classes.swift:51:37:51:37 | 4 | | {EXTERNAL LOCATION} | Int | +| classes.swift:52:7:52:8 | rc | | {EXTERNAL LOCATION} | Int | +| classes.swift:52:12:52:12 | m | | classes.swift:38:1:48:1 | Matrix | +| classes.swift:52:12:52:23 | ... .rowCount(...) | | {EXTERNAL LOCATION} | Int | +| classes.swift:59:9:59:13 | value | | {EXTERNAL LOCATION} | Int | +| classes.swift:61:5:63:5 | Block | | {EXTERNAL LOCATION} | Int | +| classes.swift:61:10:61:14 | value | | {EXTERNAL LOCATION} | Int | +| classes.swift:62:7:62:10 | self | | classes.swift:58:3:68:3 | Inner | +| classes.swift:62:7:62:16 | ... .value | | {EXTERNAL LOCATION} | Int | +| classes.swift:62:7:62:24 | ... = ... | | {EXTERNAL LOCATION} | Int | +| classes.swift:62:20:62:24 | value | | {EXTERNAL LOCATION} | Int | +| classes.swift:65:5:67:5 | Block | | {EXTERNAL LOCATION} | Int | +| classes.swift:66:14:66:17 | self | | classes.swift:58:3:68:3 | Inner | +| classes.swift:66:14:66:23 | ... .value | | {EXTERNAL LOCATION} | Int | +| classes.swift:72:7:72:11 | inner | | classes.swift:58:3:68:3 | Inner | +| classes.swift:72:15:72:36 | ... .Inner(...) | | classes.swift:58:3:68:3 | Inner | +| classes.swift:72:34:72:35 | 99 | | {EXTERNAL LOCATION} | Int | +| classes.swift:73:7:73:7 | v | | {EXTERNAL LOCATION} | Int | +| classes.swift:73:11:73:15 | inner | | classes.swift:58:3:68:3 | Inner | +| classes.swift:73:11:73:26 | ... .getValue(...) | | {EXTERNAL LOCATION} | Int | +| classes.swift:79:7:79:11 | value | | {EXTERNAL LOCATION} | Int | +| classes.swift:79:20:79:20 | 0 | | {EXTERNAL LOCATION} | Int | +| classes.swift:83:3:86:3 | Block | | classes.swift:78:1:96:1 | Builder | +| classes.swift:83:14:83:14 | v | | {EXTERNAL LOCATION} | Int | +| classes.swift:84:5:84:9 | value | | {EXTERNAL LOCATION} | Int | +| classes.swift:84:5:84:13 | ... = ... | | {EXTERNAL LOCATION} | Int | +| classes.swift:84:13:84:13 | v | | {EXTERNAL LOCATION} | Int | +| classes.swift:85:12:85:15 | self | | classes.swift:78:1:96:1 | Builder | +| classes.swift:88:3:91:3 | Block | | classes.swift:78:1:96:1 | Builder | +| classes.swift:88:14:88:14 | v | | {EXTERNAL LOCATION} | Int | +| classes.swift:89:5:89:9 | value | | {EXTERNAL LOCATION} | Int | +| classes.swift:89:5:89:14 | ... += ... | | {EXTERNAL LOCATION} | Int | +| classes.swift:89:14:89:14 | v | | {EXTERNAL LOCATION} | Int | +| classes.swift:90:12:90:15 | self | | classes.swift:78:1:96:1 | Builder | +| classes.swift:93:3:95:3 | Block | | {EXTERNAL LOCATION} | Int | +| classes.swift:94:12:94:16 | value | | {EXTERNAL LOCATION} | Int | +| classes.swift:99:7:99:7 | b | | classes.swift:78:1:96:1 | Builder | +| classes.swift:99:11:99:19 | Builder(...) | | classes.swift:78:1:96:1 | Builder | +| classes.swift:100:7:100:12 | result | | {EXTERNAL LOCATION} | Int | +| classes.swift:100:16:100:16 | b | | classes.swift:78:1:96:1 | Builder | +| classes.swift:100:16:100:24 | ... .set(...) | | classes.swift:78:1:96:1 | Builder | +| classes.swift:100:16:100:31 | ... .add(...) | | classes.swift:78:1:96:1 | Builder | +| classes.swift:100:16:100:39 | ... .build(...) | | {EXTERNAL LOCATION} | Int | +| classes.swift:100:22:100:23 | 10 | | {EXTERNAL LOCATION} | Int | +| classes.swift:100:30:100:30 | 5 | | {EXTERNAL LOCATION} | Int | +| classes.swift:108:3:110:3 | Block | | {EXTERNAL LOCATION} | Int | +| classes.swift:108:14:108:20 | retries | | {EXTERNAL LOCATION} | Int | +| classes.swift:108:29:108:29 | 3 | | {EXTERNAL LOCATION} | Int | +| classes.swift:108:32:108:38 | timeout | | {EXTERNAL LOCATION} | Double | +| classes.swift:109:12:109:18 | retries | | {EXTERNAL LOCATION} | Int | +| classes.swift:114:7:114:9 | cfg | | classes.swift:105:1:111:1 | Config | +| classes.swift:114:13:114:20 | Config(...) | | classes.swift:105:1:111:1 | Config | +| classes.swift:115:7:115:8 | r1 | | {EXTERNAL LOCATION} | Int | +| classes.swift:115:12:115:14 | cfg | | classes.swift:105:1:111:1 | Config | +| classes.swift:115:12:115:22 | ... .setup(...) | | {EXTERNAL LOCATION} | Int | +| classes.swift:116:7:116:8 | r2 | | {EXTERNAL LOCATION} | Int | +| classes.swift:116:12:116:14 | cfg | | classes.swift:105:1:111:1 | Config | +| classes.swift:116:12:116:32 | ... .setup(...) | | {EXTERNAL LOCATION} | Int | +| classes.swift:116:31:116:31 | 5 | | {EXTERNAL LOCATION} | Int | +| classes.swift:117:7:117:8 | r3 | | {EXTERNAL LOCATION} | Int | +| classes.swift:117:12:117:14 | cfg | | classes.swift:105:1:111:1 | Config | +| classes.swift:117:12:117:47 | ... .setup(...) | | {EXTERNAL LOCATION} | Int | +| classes.swift:117:31:117:31 | 2 | | {EXTERNAL LOCATION} | Int | +| classes.swift:123:7:123:13 | celsius | | {EXTERNAL LOCATION} | Double | +| classes.swift:125:3:127:3 | Block | | {EXTERNAL LOCATION} | Double | +| classes.swift:125:8:125:14 | celsius | | {EXTERNAL LOCATION} | Double | +| classes.swift:126:5:126:8 | self | | classes.swift:122:1:136:1 | Temperature | +| classes.swift:126:5:126:16 | ... .celsius | | {EXTERNAL LOCATION} | Double | +| classes.swift:126:5:126:26 | ... = ... | | {EXTERNAL LOCATION} | Double | +| classes.swift:126:20:126:26 | celsius | | {EXTERNAL LOCATION} | Double | +| classes.swift:129:3:131:3 | Block | | {EXTERNAL LOCATION} | Double | +| classes.swift:130:12:130:18 | celsius | | {EXTERNAL LOCATION} | Double | +| classes.swift:134:12:134:18 | celsius | | {EXTERNAL LOCATION} | Double | +| classes.swift:139:7:139:7 | t | | classes.swift:122:1:136:1 | Temperature | +| classes.swift:139:11:139:37 | Temperature(...) | | classes.swift:122:1:136:1 | Temperature | +| classes.swift:140:7:140:7 | c | | {EXTERNAL LOCATION} | Double | +| classes.swift:140:11:140:11 | t | | classes.swift:122:1:136:1 | Temperature | +| classes.swift:140:11:140:23 | ... .toCelsius(...) | | {EXTERNAL LOCATION} | Double | +| classes.swift:141:7:141:7 | f | | {EXTERNAL LOCATION} | Double | +| classes.swift:141:11:141:11 | t | | classes.swift:122:1:136:1 | Temperature | +| classes.swift:141:11:141:26 | ... .toFahrenheit(...) | | {EXTERNAL LOCATION} | Double | +| classes.swift:149:3:151:3 | Block | | {EXTERNAL LOCATION} | String | +| classes.swift:150:12:150:16 | "..." | | {EXTERNAL LOCATION} | String | +| classes.swift:155:3:157:3 | Block | | classes.swift:146:1:152:1 | Animal | +| classes.swift:156:5:156:9 | super | | classes.swift:146:1:152:1 | Animal | +| classes.swift:156:5:156:16 | ... .init(...) | | classes.swift:146:1:152:1 | Animal | +| classes.swift:159:3:161:3 | Block | | {EXTERNAL LOCATION} | String | +| classes.swift:160:12:160:17 | "Woof" | | {EXTERNAL LOCATION} | String | +| classes.swift:163:3:165:3 | Block | | {EXTERNAL LOCATION} | String | +| classes.swift:164:12:164:17 | "ball" | | {EXTERNAL LOCATION} | String | +| classes.swift:169:3:171:3 | Block | | classes.swift:146:1:152:1 | Animal | +| classes.swift:170:5:170:9 | super | | classes.swift:146:1:152:1 | Animal | +| classes.swift:170:5:170:16 | ... .init(...) | | classes.swift:146:1:152:1 | Animal | +| classes.swift:173:3:175:3 | Block | | {EXTERNAL LOCATION} | String | +| classes.swift:174:12:174:17 | "Meow" | | {EXTERNAL LOCATION} | String | +| classes.swift:179:7:179:7 | d | | classes.swift:154:1:166:1 | Dog | +| classes.swift:179:11:179:15 | Dog(...) | | classes.swift:154:1:166:1 | Dog | +| classes.swift:180:7:180:8 | ds | | {EXTERNAL LOCATION} | String | +| classes.swift:180:12:180:12 | d | | classes.swift:154:1:166:1 | Dog | +| classes.swift:180:12:180:20 | ... .speak(...) | | {EXTERNAL LOCATION} | String | +| classes.swift:181:7:181:8 | df | | {EXTERNAL LOCATION} | String | +| classes.swift:181:12:181:12 | d | | classes.swift:154:1:166:1 | Dog | +| classes.swift:181:12:181:20 | ... .fetch(...) | | {EXTERNAL LOCATION} | String | +| classes.swift:183:7:183:8 | ct | | classes.swift:168:1:176:1 | Cat | +| classes.swift:183:12:183:16 | Cat(...) | | classes.swift:168:1:176:1 | Cat | +| classes.swift:184:7:184:8 | cs | | {EXTERNAL LOCATION} | String | +| classes.swift:184:12:184:13 | ct | | classes.swift:168:1:176:1 | Cat | +| classes.swift:184:12:184:21 | ... .speak(...) | | {EXTERNAL LOCATION} | String | +| classes.swift:190:7:190:11 | count | | {EXTERNAL LOCATION} | Int | +| classes.swift:190:20:190:20 | 0 | | {EXTERNAL LOCATION} | Int | +| classes.swift:192:3:194:3 | Block | | {EXTERNAL LOCATION} | Int | +| classes.swift:193:5:193:9 | count | | {EXTERNAL LOCATION} | Int | +| classes.swift:193:5:193:14 | ... += ... | | {EXTERNAL LOCATION} | Int | +| classes.swift:193:14:193:14 | 1 | | {EXTERNAL LOCATION} | Int | +| classes.swift:196:3:198:3 | Block | | {EXTERNAL LOCATION} | Int | +| classes.swift:197:12:197:16 | count | | {EXTERNAL LOCATION} | Int | +| closures.swift:1:1:7:1 | Block | | {EXTERNAL LOCATION} | Int | +| closures.swift:2:9:2:14 | addOne | | {EXTERNAL LOCATION} | Function | +| closures.swift:2:9:2:14 | addOne | Args | {EXTERNAL LOCATION} | Tuple1 | +| closures.swift:2:9:2:14 | addOne | Args.T0 | {EXTERNAL LOCATION} | Int | +| closures.swift:2:9:2:14 | addOne | Return | {EXTERNAL LOCATION} | Int | +| closures.swift:2:18:4:5 | Block | | {EXTERNAL LOCATION} | Int | +| closures.swift:2:18:4:5 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| closures.swift:2:18:4:5 | FunctionExpr | Args | {EXTERNAL LOCATION} | Tuple1 | +| closures.swift:2:18:4:5 | FunctionExpr | Args.T0 | {EXTERNAL LOCATION} | Int | +| closures.swift:2:18:4:5 | FunctionExpr | Return | {EXTERNAL LOCATION} | Int | +| closures.swift:2:20:2:24 | value | | {EXTERNAL LOCATION} | Int | +| closures.swift:3:9:3:13 | value | | {EXTERNAL LOCATION} | Int | +| closures.swift:3:9:3:17 | ... + ... | | {EXTERNAL LOCATION} | Int | +| closures.swift:3:17:3:17 | 1 | | {EXTERNAL LOCATION} | Int | +| closures.swift:5:9:5:14 | result | | {EXTERNAL LOCATION} | Int | +| closures.swift:5:18:5:23 | addOne | | {EXTERNAL LOCATION} | Function | +| closures.swift:5:18:5:23 | addOne | Args | {EXTERNAL LOCATION} | Tuple1 | +| closures.swift:5:18:5:23 | addOne | Args.T0 | {EXTERNAL LOCATION} | Int | +| closures.swift:5:18:5:23 | addOne | Return | {EXTERNAL LOCATION} | Int | +| closures.swift:5:18:5:27 | addOne(...) | | {EXTERNAL LOCATION} | Int | +| closures.swift:5:25:5:26 | 41 | | {EXTERNAL LOCATION} | Int | +| closures.swift:6:5:6:5 | _ | | {EXTERNAL LOCATION} | Int | +| closures.swift:6:5:6:14 | ... = ... | | {EXTERNAL LOCATION} | Int | +| closures.swift:6:9:6:14 | result | | {EXTERNAL LOCATION} | Int | +| closures.swift:9:1:11:1 | Block | | {EXTERNAL LOCATION} | String | +| closures.swift:9:28:9:35 | callback | | {EXTERNAL LOCATION} | Function | +| closures.swift:9:28:9:35 | callback | Args | {EXTERNAL LOCATION} | Tuple1 | +| closures.swift:9:28:9:35 | callback | Args.T0 | {EXTERNAL LOCATION} | Int | +| closures.swift:9:28:9:35 | callback | Return | {EXTERNAL LOCATION} | String | +| closures.swift:9:38:9:52 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| closures.swift:9:38:9:52 | FunctionExpr | Return | {EXTERNAL LOCATION} | String | +| closures.swift:10:5:10:12 | callback | | {EXTERNAL LOCATION} | Function | +| closures.swift:10:5:10:12 | callback | Args | {EXTERNAL LOCATION} | Tuple1 | +| closures.swift:10:5:10:12 | callback | Args.T0 | {EXTERNAL LOCATION} | Int | +| closures.swift:10:5:10:12 | callback | Return | {EXTERNAL LOCATION} | String | +| closures.swift:10:5:10:16 | callback(...) | | {EXTERNAL LOCATION} | String | +| closures.swift:10:14:10:15 | 42 | | {EXTERNAL LOCATION} | Int | +| closures.swift:13:1:16:1 | Block | | closures.swift:13:30:13:31 | T1 | +| closures.swift:13:36:13:43 | callback | | {EXTERNAL LOCATION} | Function | +| closures.swift:13:36:13:43 | callback | Args | {EXTERNAL LOCATION} | Tuple1 | +| closures.swift:13:36:13:43 | callback | Args.T0 | closures.swift:13:30:13:31 | T1 | +| closures.swift:13:46:13:57 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| closures.swift:13:62:13:64 | arg | | closures.swift:13:30:13:31 | T1 | +| closures.swift:14:5:14:12 | callback | | {EXTERNAL LOCATION} | Function | +| closures.swift:14:5:14:12 | callback | Args | {EXTERNAL LOCATION} | Tuple1 | +| closures.swift:14:5:14:12 | callback | Args.T0 | closures.swift:13:30:13:31 | T1 | +| closures.swift:14:14:14:16 | arg | | closures.swift:13:30:13:31 | T1 | +| closures.swift:15:12:15:14 | arg | | closures.swift:13:30:13:31 | T1 | +| closures.swift:18:1:29:1 | Block | | {EXTERNAL LOCATION} | Bool | +| closures.swift:19:9:19:14 | result | | {EXTERNAL LOCATION} | String | +| closures.swift:19:18:21:5 | callWithIntCallback(...) | | {EXTERNAL LOCATION} | String | +| closures.swift:19:38:21:5 | Block | | {EXTERNAL LOCATION} | String | +| closures.swift:19:38:21:5 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| closures.swift:19:38:21:5 | FunctionExpr | Args | {EXTERNAL LOCATION} | Tuple1 | +| closures.swift:19:38:21:5 | FunctionExpr | Args.T0 | {EXTERNAL LOCATION} | Int | +| closures.swift:19:38:21:5 | FunctionExpr | Return | {EXTERNAL LOCATION} | String | +| closures.swift:19:40:19:44 | value | | {EXTERNAL LOCATION} | Int | +| closures.swift:20:9:20:21 | String(...) | | {EXTERNAL LOCATION} | String | +| closures.swift:20:16:20:20 | value | | {EXTERNAL LOCATION} | Int | +| closures.swift:22:5:22:5 | _ | | {EXTERNAL LOCATION} | String | +| closures.swift:22:5:22:14 | ... = ... | | {EXTERNAL LOCATION} | String | +| closures.swift:22:9:22:14 | result | | {EXTERNAL LOCATION} | String | +| closures.swift:24:9:24:21 | genericResult | | {EXTERNAL LOCATION} | Bool | +| closures.swift:24:25:27:17 | callWithGenericCallback(...) | | {EXTERNAL LOCATION} | Bool | +| closures.swift:25:9:27:9 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| closures.swift:25:9:27:9 | FunctionExpr | Args | {EXTERNAL LOCATION} | Tuple1 | +| closures.swift:25:9:27:9 | FunctionExpr | Args.T0 | {EXTERNAL LOCATION} | Bool | +| closures.swift:25:11:25:15 | value | | {EXTERNAL LOCATION} | Bool | +| closures.swift:27:12:27:16 | false | | {EXTERNAL LOCATION} | Bool | +| closures.swift:28:5:28:5 | _ | | {EXTERNAL LOCATION} | Bool | +| closures.swift:28:5:28:21 | ... = ... | | {EXTERNAL LOCATION} | Bool | +| closures.swift:28:9:28:21 | genericResult | | {EXTERNAL LOCATION} | Bool | +| closures.swift:32:9:32:9 | f | | {EXTERNAL LOCATION} | Function | +| closures.swift:32:9:32:9 | f | Args | {EXTERNAL LOCATION} | Tuple1 | +| closures.swift:32:9:32:9 | f | Args.T0 | {EXTERNAL LOCATION} | Int | +| closures.swift:32:9:32:9 | f | Return | {EXTERNAL LOCATION} | Int | +| closures.swift:32:12:32:23 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| closures.swift:32:12:32:23 | FunctionExpr | Return | {EXTERNAL LOCATION} | Int | +| closures.swift:34:5:36:5 | Block | | {EXTERNAL LOCATION} | Int | +| closures.swift:34:10:34:10 | f | | {EXTERNAL LOCATION} | Function | +| closures.swift:34:10:34:10 | f | Args | {EXTERNAL LOCATION} | Tuple1 | +| closures.swift:34:10:34:10 | f | Args.T0 | {EXTERNAL LOCATION} | Int | +| closures.swift:34:10:34:10 | f | Return | {EXTERNAL LOCATION} | Int | +| closures.swift:34:14:34:18 | value | | {EXTERNAL LOCATION} | Int | +| closures.swift:35:16:35:16 | 0 | | {EXTERNAL LOCATION} | Int | +| closures.swift:38:9:38:10 | f2 | | {EXTERNAL LOCATION} | Function | +| closures.swift:38:9:38:10 | f2 | Args | {EXTERNAL LOCATION} | Tuple1 | +| closures.swift:38:9:38:10 | f2 | Args.T0 | {EXTERNAL LOCATION} | Int | +| closures.swift:38:9:38:10 | f2 | Return | {EXTERNAL LOCATION} | Int | +| closures.swift:38:13:38:24 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| closures.swift:38:13:38:24 | FunctionExpr | Return | {EXTERNAL LOCATION} | Int | +| closures.swift:41:9:41:12 | self | | closures.swift:31:1:49:1 | C | +| closures.swift:41:9:41:14 | ... .f | | {EXTERNAL LOCATION} | Function | +| closures.swift:41:9:41:14 | ... .f | Args | {EXTERNAL LOCATION} | Tuple1 | +| closures.swift:41:9:41:14 | ... .f | Args.T0 | {EXTERNAL LOCATION} | Int | +| closures.swift:41:9:41:14 | ... .f | Return | {EXTERNAL LOCATION} | Int | +| closures.swift:42:9:42:12 | self | | closures.swift:31:1:49:1 | C | +| closures.swift:42:9:42:15 | ... .f2 | | {EXTERNAL LOCATION} | Function | +| closures.swift:42:9:42:15 | ... .f2 | Args | {EXTERNAL LOCATION} | Tuple1 | +| closures.swift:42:9:42:15 | ... .f2 | Args.T0 | {EXTERNAL LOCATION} | Int | +| closures.swift:42:9:42:15 | ... .f2 | Return | {EXTERNAL LOCATION} | Int | +| closures.swift:45:5:48:5 | Block | | {EXTERNAL LOCATION} | Int | +| closures.swift:45:24:45:28 | value | | {EXTERNAL LOCATION} | Int | +| closures.swift:46:9:46:12 | self | | closures.swift:31:1:49:1 | C | +| closures.swift:46:9:46:14 | ... .f | | {EXTERNAL LOCATION} | Function | +| closures.swift:46:9:46:14 | ... .f | Args | {EXTERNAL LOCATION} | Tuple1 | +| closures.swift:46:9:46:14 | ... .f | Args.T0 | {EXTERNAL LOCATION} | Int | +| closures.swift:46:9:46:14 | ... .f | Return | {EXTERNAL LOCATION} | Int | +| closures.swift:46:9:46:21 | ... .f(...) | | {EXTERNAL LOCATION} | Int | +| closures.swift:46:16:46:20 | value | | {EXTERNAL LOCATION} | Int | +| closures.swift:47:16:47:19 | self | | closures.swift:31:1:49:1 | C | +| closures.swift:47:16:47:22 | ... .f2 | | {EXTERNAL LOCATION} | Function | +| closures.swift:47:16:47:22 | ... .f2 | Args | {EXTERNAL LOCATION} | Tuple1 | +| closures.swift:47:16:47:22 | ... .f2 | Args.T0 | {EXTERNAL LOCATION} | Int | +| closures.swift:47:16:47:22 | ... .f2 | Return | {EXTERNAL LOCATION} | Int | +| closures.swift:47:16:47:29 | ... .f2(...) | | {EXTERNAL LOCATION} | Int | +| closures.swift:47:24:47:28 | value | | {EXTERNAL LOCATION} | Int | +| context.swift:2:7:2:13 | numbers | | {EXTERNAL LOCATION} | Array | +| context.swift:2:7:2:13 | numbers | Element | {EXTERNAL LOCATION} | Int | +| context.swift:2:17:2:25 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | +| context.swift:2:17:2:25 | ArrayLiteral | Element | {EXTERNAL LOCATION} | Int | +| context.swift:2:18:2:18 | 1 | | {EXTERNAL LOCATION} | Int | +| context.swift:2:21:2:21 | 2 | | {EXTERNAL LOCATION} | Int | +| context.swift:2:24:2:24 | 3 | | {EXTERNAL LOCATION} | Int | +| context.swift:4:7:4:13 | strings | | {EXTERNAL LOCATION} | Array | +| context.swift:4:7:4:13 | strings | Element | {EXTERNAL LOCATION} | String | +| context.swift:4:17:4:23 | numbers | | {EXTERNAL LOCATION} | Array | +| context.swift:4:17:4:23 | numbers | Element | {EXTERNAL LOCATION} | Int | +| context.swift:4:17:6:3 | ... .map(...) | | {EXTERNAL LOCATION} | Array | +| context.swift:4:17:6:3 | ... .map(...) | Element | {EXTERNAL LOCATION} | String | +| context.swift:4:29:6:3 | Block | | {EXTERNAL LOCATION} | String | +| context.swift:4:29:6:3 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| context.swift:4:29:6:3 | FunctionExpr | Args | {EXTERNAL LOCATION} | Tuple1 | +| context.swift:4:29:6:3 | FunctionExpr | Args.T0 | {EXTERNAL LOCATION} | Int | +| context.swift:4:29:6:3 | FunctionExpr | Return | {EXTERNAL LOCATION} | String | +| context.swift:4:31:4:31 | x | | {EXTERNAL LOCATION} | Int | +| context.swift:5:5:5:13 | String(...) | | {EXTERNAL LOCATION} | String | +| context.swift:5:12:5:12 | x | | {EXTERNAL LOCATION} | Int | +| fields.swift:2:7:2:20 | inheritedField | | {EXTERNAL LOCATION} | Int | +| fields.swift:2:29:2:29 | 0 | | {EXTERNAL LOCATION} | Int | +| fields.swift:6:7:6:17 | storedField | | {EXTERNAL LOCATION} | String | +| fields.swift:6:29:6:36 | "stored" | | {EXTERNAL LOCATION} | String | +| fields.swift:7:7:7:18 | genericField | | fields.swift:5:22:5:22 | T | +| fields.swift:9:3:11:3 | Block | | fields.swift:5:22:5:22 | T | +| fields.swift:9:8:9:19 | genericField | | fields.swift:5:22:5:22 | T | +| fields.swift:10:5:10:8 | self | | fields.swift:5:1:20:1 | FieldContainer | +| fields.swift:10:5:10:8 | self | T | fields.swift:5:22:5:22 | T | +| fields.swift:10:5:10:21 | ... .genericField | | fields.swift:5:22:5:22 | T | +| fields.swift:10:5:10:36 | ... = ... | | fields.swift:5:22:5:22 | T | +| fields.swift:10:25:10:36 | genericField | | fields.swift:5:22:5:22 | T | +| fields.swift:13:3:15:3 | Block | | {EXTERNAL LOCATION} | String | +| fields.swift:14:12:14:22 | storedField | | {EXTERNAL LOCATION} | String | +| fields.swift:17:3:19:3 | Block | | fields.swift:5:22:5:22 | T | +| fields.swift:18:12:18:15 | self | | fields.swift:5:1:20:1 | FieldContainer | +| fields.swift:18:12:18:15 | self | T | fields.swift:5:22:5:22 | T | +| fields.swift:18:12:18:28 | ... .genericField | | fields.swift:5:22:5:22 | T | +| fields.swift:23:14:23:24 | staticField | | {EXTERNAL LOCATION} | Bool | +| fields.swift:23:34:23:37 | true | | {EXTERNAL LOCATION} | Bool | +| fields.swift:27:7:27:11 | value | | {EXTERNAL LOCATION} | Double | +| fields.swift:31:7:31:12 | nested | | fields.swift:26:1:28:1 | NestedField | +| fields.swift:35:7:35:15 | container | | fields.swift:5:1:20:1 | FieldContainer | +| fields.swift:35:7:35:15 | container | T | {EXTERNAL LOCATION} | Int | +| fields.swift:35:19:35:50 | FieldContainer(...) | | fields.swift:5:1:20:1 | FieldContainer | +| fields.swift:35:19:35:50 | FieldContainer(...) | T | {EXTERNAL LOCATION} | Int | +| fields.swift:35:48:35:49 | 42 | | {EXTERNAL LOCATION} | Int | +| fields.swift:36:7:36:12 | stored | | {EXTERNAL LOCATION} | String | +| fields.swift:36:16:36:24 | container | | fields.swift:5:1:20:1 | FieldContainer | +| fields.swift:36:16:36:24 | container | T | {EXTERNAL LOCATION} | Int | +| fields.swift:36:16:36:36 | ... .storedField | | {EXTERNAL LOCATION} | String | +| fields.swift:37:7:37:13 | generic | | {EXTERNAL LOCATION} | Int | +| fields.swift:37:17:37:25 | container | | fields.swift:5:1:20:1 | FieldContainer | +| fields.swift:37:17:37:25 | container | T | {EXTERNAL LOCATION} | Int | +| fields.swift:37:17:37:38 | ... .genericField | | {EXTERNAL LOCATION} | Int | +| fields.swift:38:7:38:15 | inherited | | {EXTERNAL LOCATION} | Int | +| fields.swift:38:19:38:27 | container | | fields.swift:5:1:20:1 | FieldContainer | +| fields.swift:38:19:38:27 | container | T | {EXTERNAL LOCATION} | Int | +| fields.swift:38:19:38:42 | ... .inheritedField | | {EXTERNAL LOCATION} | Int | +| fields.swift:39:7:39:17 | staticValue | | {EXTERNAL LOCATION} | Bool | +| fields.swift:39:21:39:52 | ... .staticField | | {EXTERNAL LOCATION} | Bool | +| generics.swift:3:1:5:1 | Block | | generics.swift:3:15:3:15 | T | +| generics.swift:3:20:3:20 | x | | generics.swift:3:15:3:15 | T | +| generics.swift:4:10:4:10 | x | | generics.swift:3:15:3:15 | T | +| generics.swift:7:23:7:23 | a | | generics.swift:7:15:7:16 | A | +| generics.swift:7:31:7:31 | b | | generics.swift:7:18:7:18 | B | +| generics.swift:8:11:8:11 | a | | generics.swift:7:15:7:16 | A | +| generics.swift:8:14:8:14 | b | | generics.swift:7:18:7:18 | B | +| generics.swift:12:7:12:7 | i | | {EXTERNAL LOCATION} | Int | +| generics.swift:12:11:12:22 | identity(...) | | {EXTERNAL LOCATION} | Int | +| generics.swift:12:20:12:21 | 42 | | {EXTERNAL LOCATION} | Int | +| generics.swift:13:7:13:7 | s | | {EXTERNAL LOCATION} | String | +| generics.swift:13:11:13:27 | identity(...) | | {EXTERNAL LOCATION} | String | +| generics.swift:13:20:13:26 | "hello" | | {EXTERNAL LOCATION} | String | +| generics.swift:14:7:14:7 | p | | {EXTERNAL LOCATION} | Tuple2 | +| generics.swift:14:7:14:7 | p | T0 | {EXTERNAL LOCATION} | Int | +| generics.swift:14:7:14:7 | p | T1 | {EXTERNAL LOCATION} | String | +| generics.swift:14:11:14:28 | makePair(...) | | {EXTERNAL LOCATION} | Tuple2 | +| generics.swift:14:11:14:28 | makePair(...) | T0 | {EXTERNAL LOCATION} | Int | +| generics.swift:14:11:14:28 | makePair(...) | T1 | {EXTERNAL LOCATION} | String | +| generics.swift:14:20:14:20 | 1 | | {EXTERNAL LOCATION} | Int | +| generics.swift:14:23:14:27 | "two" | | {EXTERNAL LOCATION} | String | +| generics.swift:20:7:20:11 | first | | generics.swift:19:13:19:14 | A | +| generics.swift:21:7:21:12 | second | | generics.swift:19:16:19:16 | B | +| generics.swift:23:3:26:3 | Block | | generics.swift:19:16:19:16 | B | +| generics.swift:23:8:23:12 | first | | generics.swift:19:13:19:14 | A | +| generics.swift:23:18:23:23 | second | | generics.swift:19:16:19:16 | B | +| generics.swift:24:5:24:8 | self | | generics.swift:19:1:35:1 | Pair | +| generics.swift:24:5:24:8 | self | A | generics.swift:19:13:19:14 | A | +| generics.swift:24:5:24:8 | self | B | generics.swift:19:16:19:16 | B | +| generics.swift:24:5:24:14 | ... .first | | generics.swift:19:13:19:14 | A | +| generics.swift:24:5:24:22 | ... = ... | | generics.swift:19:13:19:14 | A | +| generics.swift:24:18:24:22 | first | | generics.swift:19:13:19:14 | A | +| generics.swift:25:5:25:8 | self | | generics.swift:19:1:35:1 | Pair | +| generics.swift:25:5:25:8 | self | A | generics.swift:19:13:19:14 | A | +| generics.swift:25:5:25:8 | self | B | generics.swift:19:16:19:16 | B | +| generics.swift:25:5:25:15 | ... .second | | generics.swift:19:16:19:16 | B | +| generics.swift:25:5:25:24 | ... = ... | | generics.swift:19:16:19:16 | B | +| generics.swift:25:19:25:24 | second | | generics.swift:19:16:19:16 | B | +| generics.swift:28:3:30:3 | Block | | generics.swift:19:13:19:14 | A | +| generics.swift:29:12:29:16 | first | | generics.swift:19:13:19:14 | A | +| generics.swift:32:3:34:3 | Block | | generics.swift:19:16:19:16 | B | +| generics.swift:33:12:33:17 | second | | generics.swift:19:16:19:16 | B | +| generics.swift:38:7:38:7 | p | | generics.swift:19:1:35:1 | Pair | +| generics.swift:38:7:38:7 | p | A | {EXTERNAL LOCATION} | Int | +| generics.swift:38:7:38:7 | p | B | {EXTERNAL LOCATION} | String | +| generics.swift:38:11:38:37 | Pair(...) | | generics.swift:19:1:35:1 | Pair | +| generics.swift:38:11:38:37 | Pair(...) | A | {EXTERNAL LOCATION} | Int | +| generics.swift:38:11:38:37 | Pair(...) | B | {EXTERNAL LOCATION} | String | +| generics.swift:38:23:38:23 | 1 | | {EXTERNAL LOCATION} | Int | +| generics.swift:38:34:38:36 | "x" | | {EXTERNAL LOCATION} | String | +| generics.swift:39:7:39:7 | f | | {EXTERNAL LOCATION} | Int | +| generics.swift:39:11:39:11 | p | | generics.swift:19:1:35:1 | Pair | +| generics.swift:39:11:39:11 | p | A | {EXTERNAL LOCATION} | Int | +| generics.swift:39:11:39:11 | p | B | {EXTERNAL LOCATION} | String | +| generics.swift:39:11:39:22 | ... .getFirst(...) | | {EXTERNAL LOCATION} | Int | +| generics.swift:40:7:40:8 | sc | | {EXTERNAL LOCATION} | String | +| generics.swift:40:12:40:12 | p | | generics.swift:19:1:35:1 | Pair | +| generics.swift:40:12:40:12 | p | A | {EXTERNAL LOCATION} | Int | +| generics.swift:40:12:40:12 | p | B | {EXTERNAL LOCATION} | String | +| generics.swift:40:12:40:24 | ... .getSecond(...) | | {EXTERNAL LOCATION} | String | +| generics.swift:50:12:50:15 | self | | generics.swift:45:1:57:1 | Result | +| generics.swift:50:12:50:15 | self | T | generics.swift:45:13:45:13 | T | +| generics.swift:51:10:51:24 | ... .success(...) | | generics.swift:45:1:57:1 | Result | +| generics.swift:51:10:51:24 | ... .success(...) | T | generics.swift:45:13:45:13 | T | +| generics.swift:53:10:53:17 | ... .failure | | generics.swift:45:1:57:1 | Result | +| generics.swift:53:10:53:17 | ... .failure | T | generics.swift:45:13:45:13 | T | +| generics.swift:60:7:60:7 | r | | generics.swift:45:1:57:1 | Result | +| generics.swift:60:7:60:7 | r | T | {EXTERNAL LOCATION} | Int | +| generics.swift:60:11:60:28 | ... .success(...) | | generics.swift:45:1:57:1 | Result | +| generics.swift:60:11:60:28 | ... .success(...) | T | {EXTERNAL LOCATION} | Int | +| generics.swift:60:26:60:27 | 42 | | {EXTERNAL LOCATION} | Int | +| generics.swift:61:7:61:7 | v | | {EXTERNAL LOCATION} | Optional | +| generics.swift:61:7:61:7 | v | Wrapped | {EXTERNAL LOCATION} | Int | +| generics.swift:61:11:61:11 | r | | generics.swift:45:1:57:1 | Result | +| generics.swift:61:11:61:11 | r | T | {EXTERNAL LOCATION} | Int | +| generics.swift:61:11:61:22 | ... .getValue(...) | | {EXTERNAL LOCATION} | Optional | +| generics.swift:61:11:61:22 | ... .getValue(...) | Wrapped | {EXTERNAL LOCATION} | Int | +| generics.swift:63:7:63:8 | r2 | | generics.swift:45:1:57:1 | Result | +| generics.swift:63:7:63:8 | r2 | T | {EXTERNAL LOCATION} | Int | +| generics.swift:63:34:63:35 | 42 | | {EXTERNAL LOCATION} | Int | +| generics.swift:64:7:64:8 | v2 | | {EXTERNAL LOCATION} | Optional | +| generics.swift:64:7:64:8 | v2 | Wrapped | {EXTERNAL LOCATION} | Int | +| generics.swift:64:12:64:13 | r2 | | generics.swift:45:1:57:1 | Result | +| generics.swift:64:12:64:13 | r2 | T | {EXTERNAL LOCATION} | Int | +| generics.swift:64:12:64:24 | ... .getValue(...) | | {EXTERNAL LOCATION} | Optional | +| generics.swift:64:12:64:24 | ... .getValue(...) | Wrapped | {EXTERNAL LOCATION} | Int | +| generics.swift:69:1:72:1 | Block | | generics.swift:69:24:69:24 | U | +| generics.swift:69:29:69:33 | value | | generics.swift:69:21:69:22 | T | +| generics.swift:69:41:69:49 | transform | | {EXTERNAL LOCATION} | Function | +| generics.swift:69:41:69:49 | transform | Args | {EXTERNAL LOCATION} | Tuple1 | +| generics.swift:69:41:69:49 | transform | Args.T0 | generics.swift:69:21:69:22 | T | +| generics.swift:69:41:69:49 | transform | Return | generics.swift:69:24:69:24 | U | +| generics.swift:69:52:69:59 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| generics.swift:69:52:69:59 | FunctionExpr | Return | generics.swift:69:24:69:24 | U | +| generics.swift:70:7:70:12 | result | | generics.swift:69:24:69:24 | U | +| generics.swift:70:16:70:24 | transform | | {EXTERNAL LOCATION} | Function | +| generics.swift:70:16:70:24 | transform | Args | {EXTERNAL LOCATION} | Tuple1 | +| generics.swift:70:16:70:24 | transform | Args.T0 | generics.swift:69:21:69:22 | T | +| generics.swift:70:16:70:24 | transform | Return | generics.swift:69:24:69:24 | U | +| generics.swift:70:16:70:31 | transform(...) | | generics.swift:69:24:69:24 | U | +| generics.swift:70:26:70:30 | value | | generics.swift:69:21:69:22 | T | +| generics.swift:71:10:71:15 | result | | generics.swift:69:24:69:24 | U | +| generics.swift:75:7:75:12 | result | | {EXTERNAL LOCATION} | Int | +| generics.swift:75:16:75:48 | applyTransform(...) | | {EXTERNAL LOCATION} | Int | +| generics.swift:75:31:75:31 | 5 | | {EXTERNAL LOCATION} | Int | +| generics.swift:75:34:75:47 | Block | | {EXTERNAL LOCATION} | Int | +| generics.swift:75:34:75:47 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| generics.swift:75:34:75:47 | FunctionExpr | Args | {EXTERNAL LOCATION} | Tuple1 | +| generics.swift:75:34:75:47 | FunctionExpr | Args.T0 | {EXTERNAL LOCATION} | Int | +| generics.swift:75:34:75:47 | FunctionExpr | Return | {EXTERNAL LOCATION} | Int | +| generics.swift:75:36:75:36 | x | | {EXTERNAL LOCATION} | Int | +| generics.swift:75:41:75:41 | x | | {EXTERNAL LOCATION} | Int | +| generics.swift:75:41:75:45 | ... * ... | | {EXTERNAL LOCATION} | Int | +| generics.swift:75:45:75:45 | 2 | | {EXTERNAL LOCATION} | Int | +| generics.swift:76:7:76:13 | strings | | {EXTERNAL LOCATION} | String | +| generics.swift:76:17:80:6 | applyTransform(...) | | {EXTERNAL LOCATION} | String | +| generics.swift:77:5:77:6 | 10 | | {EXTERNAL LOCATION} | Int | +| generics.swift:78:5:80:5 | Block | | {EXTERNAL LOCATION} | String | +| generics.swift:78:5:80:5 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| generics.swift:78:5:80:5 | FunctionExpr | Args | {EXTERNAL LOCATION} | Tuple1 | +| generics.swift:78:5:80:5 | FunctionExpr | Args.T0 | {EXTERNAL LOCATION} | Int | +| generics.swift:78:5:80:5 | FunctionExpr | Return | {EXTERNAL LOCATION} | String | +| generics.swift:79:7:79:7 | x | | {EXTERNAL LOCATION} | Int | +| generics.swift:79:12:79:20 | String(...) | | {EXTERNAL LOCATION} | String | +| generics.swift:79:19:79:19 | x | | {EXTERNAL LOCATION} | Int | +| generics.swift:94:7:94:11 | inner | | generics.swift:93:15:93:27 | T | +| generics.swift:96:3:98:3 | Block | | generics.swift:93:15:93:27 | T | +| generics.swift:96:10:96:14 | inner | | generics.swift:93:15:93:27 | T | +| generics.swift:97:5:97:8 | self | | generics.swift:93:1:113:1 | Wrapper | +| generics.swift:97:5:97:8 | self | T | generics.swift:93:15:93:27 | T | +| generics.swift:97:5:97:14 | ... .inner | | generics.swift:93:15:93:27 | T | +| generics.swift:97:5:97:22 | ... = ... | | generics.swift:93:15:93:27 | T | +| generics.swift:97:18:97:22 | inner | | generics.swift:93:15:93:27 | T | +| generics.swift:100:3:102:3 | Block | | generics.swift:93:15:93:27 | T | +| generics.swift:101:12:101:16 | inner | | generics.swift:93:15:93:27 | T | +| generics.swift:105:13:105:17 | inner | | generics.swift:93:15:93:27 | T | +| generics.swift:110:13:110:17 | inner | | generics.swift:93:15:93:27 | T | +| generics.swift:118:3:120:3 | Block | | {EXTERNAL LOCATION} | Int | +| generics.swift:119:12:119:15 | self | | {EXTERNAL LOCATION} | Int | +| generics.swift:119:12:119:19 | ... * ... | | {EXTERNAL LOCATION} | Int | +| generics.swift:119:19:119:19 | 2 | | {EXTERNAL LOCATION} | Int | +| generics.swift:122:3:124:3 | Block | | {EXTERNAL LOCATION} | String | +| generics.swift:123:12:123:19 | "number" | | {EXTERNAL LOCATION} | String | +| generics.swift:128:7:128:7 | w | | generics.swift:93:1:113:1 | Wrapper | +| generics.swift:128:7:128:7 | w | T | {EXTERNAL LOCATION} | Int | +| generics.swift:128:11:128:21 | Wrapper(...) | | generics.swift:93:1:113:1 | Wrapper | +| generics.swift:128:11:128:21 | Wrapper(...) | T | {EXTERNAL LOCATION} | Int | +| generics.swift:128:19:128:20 | 42 | | {EXTERNAL LOCATION} | Int | +| generics.swift:129:7:129:7 | v | | {EXTERNAL LOCATION} | Int | +| generics.swift:129:11:129:11 | w | | generics.swift:93:1:113:1 | Wrapper | +| generics.swift:129:11:129:11 | w | T | {EXTERNAL LOCATION} | Int | +| generics.swift:129:11:129:17 | ... .get(...) | | {EXTERNAL LOCATION} | Int | +| generics.swift:130:7:130:7 | z | | {EXTERNAL LOCATION} | Int | +| generics.swift:130:11:130:11 | w | | generics.swift:93:1:113:1 | Wrapper | +| generics.swift:130:11:130:11 | w | T | {EXTERNAL LOCATION} | Int | +| generics.swift:130:11:130:21 | ... .callFoo(...) | | {EXTERNAL LOCATION} | Int | +| generics.swift:136:7:136:12 | value1 | | generics.swift:135:12:135:14 | T1 | +| generics.swift:137:7:137:12 | value2 | | generics.swift:135:16:135:17 | T2 | +| generics.swift:139:3:142:3 | Block | | generics.swift:135:16:135:17 | T2 | +| generics.swift:139:10:139:11 | v1 | | generics.swift:135:12:135:14 | T1 | +| generics.swift:139:20:139:21 | v2 | | generics.swift:135:16:135:17 | T2 | +| generics.swift:140:5:140:8 | self | | generics.swift:135:1:151:1 | Base | +| generics.swift:140:5:140:8 | self | T1 | generics.swift:135:12:135:14 | T1 | +| generics.swift:140:5:140:8 | self | T2 | generics.swift:135:16:135:17 | T2 | +| generics.swift:140:5:140:15 | ... .value1 | | generics.swift:135:12:135:14 | T1 | +| generics.swift:140:5:140:20 | ... = ... | | generics.swift:135:12:135:14 | T1 | +| generics.swift:140:19:140:20 | v1 | | generics.swift:135:12:135:14 | T1 | +| generics.swift:141:5:141:8 | self | | generics.swift:135:1:151:1 | Base | +| generics.swift:141:5:141:8 | self | T1 | generics.swift:135:12:135:14 | T1 | +| generics.swift:141:5:141:8 | self | T2 | generics.swift:135:16:135:17 | T2 | +| generics.swift:141:5:141:15 | ... .value2 | | generics.swift:135:16:135:17 | T2 | +| generics.swift:141:5:141:20 | ... = ... | | generics.swift:135:16:135:17 | T2 | +| generics.swift:141:19:141:20 | v2 | | generics.swift:135:16:135:17 | T2 | +| generics.swift:144:3:146:3 | Block | | generics.swift:135:12:135:14 | T1 | +| generics.swift:145:12:145:17 | value1 | | generics.swift:135:12:135:14 | T1 | +| generics.swift:148:3:150:3 | Block | | generics.swift:135:16:135:17 | T2 | +| generics.swift:149:12:149:17 | value2 | | generics.swift:135:16:135:17 | T2 | +| generics.swift:154:3:156:3 | Block | | generics.swift:135:1:151:1 | Base | +| generics.swift:154:3:156:3 | Block | T1 | generics.swift:153:19:153:20 | T2 | +| generics.swift:154:3:156:3 | Block | T2 | generics.swift:153:15:153:17 | T1 | +| generics.swift:154:10:154:11 | v1 | | generics.swift:153:15:153:17 | T1 | +| generics.swift:154:20:154:21 | v2 | | generics.swift:153:19:153:20 | T2 | +| generics.swift:155:5:155:9 | super | | generics.swift:135:1:151:1 | Base | +| generics.swift:155:5:155:9 | super | T1 | generics.swift:153:19:153:20 | T2 | +| generics.swift:155:5:155:9 | super | T2 | generics.swift:153:15:153:17 | T1 | +| generics.swift:155:5:155:22 | ... .init(...) | | generics.swift:135:1:151:1 | Base | +| generics.swift:155:5:155:22 | ... .init(...) | T1 | generics.swift:153:19:153:20 | T2 | +| generics.swift:155:5:155:22 | ... .init(...) | T2 | generics.swift:153:15:153:17 | T1 | +| generics.swift:155:16:155:17 | v2 | | generics.swift:153:19:153:20 | T2 | +| generics.swift:155:20:155:21 | v1 | | generics.swift:153:15:153:17 | T1 | +| generics.swift:160:3:162:3 | Block | | generics.swift:153:1:157:1 | Derived | +| generics.swift:160:3:162:3 | Block | T1 | generics.swift:159:22:159:22 | D | +| generics.swift:160:3:162:3 | Block | T2 | {EXTERNAL LOCATION} | Bool | +| generics.swift:160:10:160:10 | v | | generics.swift:159:22:159:22 | D | +| generics.swift:161:5:161:9 | super | | generics.swift:153:1:157:1 | Derived | +| generics.swift:161:5:161:9 | super | T1 | generics.swift:159:22:159:22 | D | +| generics.swift:161:5:161:9 | super | T2 | {EXTERNAL LOCATION} | Bool | +| generics.swift:161:5:161:23 | ... .init(...) | | generics.swift:153:1:157:1 | Derived | +| generics.swift:161:5:161:23 | ... .init(...) | T1 | generics.swift:159:22:159:22 | D | +| generics.swift:161:5:161:23 | ... .init(...) | T2 | {EXTERNAL LOCATION} | Bool | +| generics.swift:161:16:161:16 | v | | generics.swift:159:22:159:22 | D | +| generics.swift:161:19:161:22 | true | | {EXTERNAL LOCATION} | Bool | +| generics.swift:166:7:166:7 | d | | generics.swift:153:1:157:1 | Derived | +| generics.swift:166:7:166:7 | d | T1 | {EXTERNAL LOCATION} | Int | +| generics.swift:166:7:166:7 | d | T2 | {EXTERNAL LOCATION} | String | +| generics.swift:166:11:166:25 | Derived(...) | | generics.swift:153:1:157:1 | Derived | +| generics.swift:166:11:166:25 | Derived(...) | T1 | {EXTERNAL LOCATION} | Int | +| generics.swift:166:11:166:25 | Derived(...) | T2 | {EXTERNAL LOCATION} | String | +| generics.swift:166:19:166:19 | 1 | | {EXTERNAL LOCATION} | Int | +| generics.swift:166:22:166:24 | "x" | | {EXTERNAL LOCATION} | String | +| generics.swift:167:7:167:8 | v1 | | {EXTERNAL LOCATION} | String | +| generics.swift:167:12:167:12 | d | | generics.swift:153:1:157:1 | Derived | +| generics.swift:167:12:167:12 | d | T1 | {EXTERNAL LOCATION} | Int | +| generics.swift:167:12:167:12 | d | T2 | {EXTERNAL LOCATION} | String | +| generics.swift:167:12:167:24 | ... .getValue1(...) | | {EXTERNAL LOCATION} | String | +| generics.swift:168:7:168:8 | v2 | | {EXTERNAL LOCATION} | Int | +| generics.swift:168:12:168:12 | d | | generics.swift:153:1:157:1 | Derived | +| generics.swift:168:12:168:12 | d | T1 | {EXTERNAL LOCATION} | Int | +| generics.swift:168:12:168:12 | d | T2 | {EXTERNAL LOCATION} | String | +| generics.swift:168:12:168:24 | ... .getValue2(...) | | {EXTERNAL LOCATION} | Int | +| generics.swift:170:7:170:8 | dd | | generics.swift:159:1:163:1 | DerivedDerived | +| generics.swift:170:7:170:8 | dd | D | {EXTERNAL LOCATION} | String | +| generics.swift:170:12:170:34 | DerivedDerived(...) | | generics.swift:159:1:163:1 | DerivedDerived | +| generics.swift:170:12:170:34 | DerivedDerived(...) | D | {EXTERNAL LOCATION} | String | +| generics.swift:170:27:170:33 | "hello" | | {EXTERNAL LOCATION} | String | +| generics.swift:171:7:171:9 | vv1 | | {EXTERNAL LOCATION} | Bool | +| generics.swift:171:13:171:14 | dd | | generics.swift:159:1:163:1 | DerivedDerived | +| generics.swift:171:13:171:14 | dd | D | {EXTERNAL LOCATION} | String | +| generics.swift:171:13:171:26 | ... .getValue1(...) | | {EXTERNAL LOCATION} | Bool | +| generics.swift:172:7:172:9 | vv2 | | {EXTERNAL LOCATION} | String | +| generics.swift:172:13:172:14 | dd | | generics.swift:159:1:163:1 | DerivedDerived | +| generics.swift:172:13:172:14 | dd | D | {EXTERNAL LOCATION} | String | +| generics.swift:172:13:172:26 | ... .getValue2(...) | | {EXTERNAL LOCATION} | String | +| generics.swift:184:3:186:3 | Block | | generics.swift:177:1:181:1 | MyProtocol2 | +| generics.swift:185:12:185:15 | self | | generics.swift:177:1:181:1 | MyProtocol2 | +| generics.swift:190:7:190:11 | value | | generics.swift:189:15:189:15 | T | +| generics.swift:192:3:194:3 | Block | | generics.swift:189:15:189:15 | T | +| generics.swift:192:10:192:14 | value | | generics.swift:189:15:189:15 | T | +| generics.swift:193:5:193:8 | self | | generics.swift:189:1:195:1 | MyClass | +| generics.swift:193:5:193:8 | self | T | generics.swift:189:15:189:15 | T | +| generics.swift:193:5:193:14 | ... .value | | generics.swift:189:15:189:15 | T | +| generics.swift:193:5:193:22 | ... = ... | | generics.swift:189:15:189:15 | T | +| generics.swift:193:18:193:22 | value | | generics.swift:189:15:189:15 | T | +| generics.swift:205:32:205:32 | c | | generics.swift:205:14:205:27 | T | +| generics.swift:206:10:206:10 | c | | generics.swift:205:14:205:27 | T | +| generics.swift:209:32:209:32 | c | | generics.swift:209:14:209:27 | T | +| generics.swift:210:10:210:10 | c | | generics.swift:209:14:209:27 | T | +| generics.swift:214:7:214:7 | c | | generics.swift:189:1:195:1 | MyClass | +| generics.swift:214:7:214:7 | c | T | {EXTERNAL LOCATION} | Int | +| generics.swift:214:11:214:21 | MyClass(...) | | generics.swift:189:1:195:1 | MyClass | +| generics.swift:214:11:214:21 | MyClass(...) | T | {EXTERNAL LOCATION} | Int | +| generics.swift:214:19:214:20 | 42 | | {EXTERNAL LOCATION} | Int | +| generics.swift:215:11:215:11 | c | | generics.swift:189:1:195:1 | MyClass | +| generics.swift:215:11:215:11 | c | T | {EXTERNAL LOCATION} | Int | +| generics.swift:216:11:216:11 | c | | generics.swift:189:1:195:1 | MyClass | +| generics.swift:216:11:216:11 | c | T | {EXTERNAL LOCATION} | Int | +| generics.swift:217:20:217:20 | c | | generics.swift:189:1:195:1 | MyClass | +| generics.swift:217:20:217:20 | c | T | {EXTERNAL LOCATION} | Int | +| generics.swift:235:3:237:3 | Block | | {EXTERNAL LOCATION} | String | +| generics.swift:236:12:236:17 | "base" | | {EXTERNAL LOCATION} | String | +| generics.swift:239:3:241:3 | Block | | {EXTERNAL LOCATION} | String | +| generics.swift:240:12:240:16 | "sub" | | {EXTERNAL LOCATION} | String | +| generics.swift:244:65:244:69 | value | | generics.swift:244:33:244:60 | T | +| generics.swift:245:10:245:14 | value | | generics.swift:244:33:244:60 | T | +| generics.swift:263:3:265:3 | Block | | {EXTERNAL LOCATION} | Int | +| generics.swift:264:12:264:13 | 42 | | {EXTERNAL LOCATION} | Int | +| generics.swift:273:7:273:11 | value | | {EXTERNAL LOCATION} | Int | +| generics.swift:273:15:273:66 | getPrimaryAssociatedType(...) | | {EXTERNAL LOCATION} | Int | +| key_paths.swift:4:7:4:7 | x | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:5:7:5:7 | y | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:7:3:10:3 | Block | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:7:8:7:8 | x | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:7:19:7:19 | y | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:8:5:8:8 | self | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:8:5:8:10 | ... .x | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:8:5:8:14 | ... = ... | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:8:14:8:14 | x | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:9:5:9:8 | self | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:9:5:9:10 | ... .y | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:9:5:9:14 | ... = ... | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:9:14:9:14 | y | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:13:13:13:13 | x | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:13:13:13:17 | ... * ... | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:13:13:13:25 | ... + ... | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:13:17:13:17 | x | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:13:21:13:21 | y | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:13:21:13:25 | ... * ... | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:13:25:13:25 | y | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:18:7:18:11 | start | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:19:7:19:9 | end | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:21:3:24:3 | Block | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:21:8:21:12 | start | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:21:22:21:24 | end | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:22:5:22:8 | self | | key_paths.swift:17:1:25:1 | Line | +| key_paths.swift:22:5:22:14 | ... .start | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:22:5:22:22 | ... = ... | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:22:18:22:22 | start | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:23:5:23:8 | self | | key_paths.swift:17:1:25:1 | Line | +| key_paths.swift:23:5:23:12 | ... .end | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:23:5:23:18 | ... = ... | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:23:16:23:18 | end | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:31:7:31:7 | p | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:31:11:31:31 | Point(...) | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:32:14:32:14 | p | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:33:14:33:14 | p | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:42:7:42:7 | s | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:42:11:42:31 | Point(...) | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:43:7:43:7 | e | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:43:11:43:31 | Point(...) | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:44:7:44:10 | line | | key_paths.swift:17:1:25:1 | Line | +| key_paths.swift:44:14:44:35 | Line(...) | | key_paths.swift:17:1:25:1 | Line | +| key_paths.swift:44:26:44:26 | s | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:44:34:44:34 | e | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:45:16:45:19 | line | | key_paths.swift:17:1:25:1 | Line | +| key_paths.swift:46:14:46:17 | line | | key_paths.swift:17:1:25:1 | Line | +| key_paths.swift:53:13:53:14 | 42 | | {EXTERNAL LOCATION} | Int | +| key_paths.swift:59:7:59:10 | name | | {EXTERNAL LOCATION} | String | +| key_paths.swift:60:7:60:13 | address | | {EXTERNAL LOCATION} | Optional | +| key_paths.swift:60:7:60:13 | address | Wrapped | key_paths.swift:68:1:76:1 | Address | +| key_paths.swift:62:3:65:3 | Block | | {EXTERNAL LOCATION} | Optional | +| key_paths.swift:62:3:65:3 | Block | Wrapped | key_paths.swift:68:1:76:1 | Address | +| key_paths.swift:62:8:62:11 | name | | {EXTERNAL LOCATION} | String | +| key_paths.swift:62:22:62:28 | address | | {EXTERNAL LOCATION} | Optional | +| key_paths.swift:62:22:62:28 | address | Wrapped | key_paths.swift:68:1:76:1 | Address | +| key_paths.swift:63:5:63:8 | self | | key_paths.swift:58:1:66:1 | Person | +| key_paths.swift:63:5:63:13 | ... .name | | {EXTERNAL LOCATION} | String | +| key_paths.swift:63:5:63:20 | ... = ... | | {EXTERNAL LOCATION} | String | +| key_paths.swift:63:17:63:20 | name | | {EXTERNAL LOCATION} | String | +| key_paths.swift:64:5:64:8 | self | | key_paths.swift:58:1:66:1 | Person | +| key_paths.swift:64:5:64:16 | ... .address | | {EXTERNAL LOCATION} | Optional | +| key_paths.swift:64:5:64:16 | ... .address | Wrapped | key_paths.swift:68:1:76:1 | Address | +| key_paths.swift:64:5:64:26 | ... = ... | | {EXTERNAL LOCATION} | Optional | +| key_paths.swift:64:5:64:26 | ... = ... | Wrapped | key_paths.swift:68:1:76:1 | Address | +| key_paths.swift:64:20:64:26 | address | | {EXTERNAL LOCATION} | Optional | +| key_paths.swift:64:20:64:26 | address | Wrapped | key_paths.swift:68:1:76:1 | Address | +| key_paths.swift:69:7:69:10 | city | | {EXTERNAL LOCATION} | String | +| key_paths.swift:70:7:70:9 | zip | | {EXTERNAL LOCATION} | String | +| key_paths.swift:72:3:75:3 | Block | | {EXTERNAL LOCATION} | String | +| key_paths.swift:72:8:72:11 | city | | {EXTERNAL LOCATION} | String | +| key_paths.swift:72:22:72:24 | zip | | {EXTERNAL LOCATION} | String | +| key_paths.swift:73:5:73:8 | self | | key_paths.swift:68:1:76:1 | Address | +| key_paths.swift:73:5:73:13 | ... .city | | {EXTERNAL LOCATION} | String | +| key_paths.swift:73:5:73:20 | ... = ... | | {EXTERNAL LOCATION} | String | +| key_paths.swift:73:17:73:20 | city | | {EXTERNAL LOCATION} | String | +| key_paths.swift:74:5:74:8 | self | | key_paths.swift:68:1:76:1 | Address | +| key_paths.swift:74:5:74:12 | ... .zip | | {EXTERNAL LOCATION} | String | +| key_paths.swift:74:5:74:18 | ... = ... | | {EXTERNAL LOCATION} | String | +| key_paths.swift:74:16:74:18 | zip | | {EXTERNAL LOCATION} | String | +| key_paths.swift:80:7:80:10 | addr | | key_paths.swift:68:1:76:1 | Address | +| key_paths.swift:80:14:80:47 | Address(...) | | key_paths.swift:68:1:76:1 | Address | +| key_paths.swift:80:28:80:32 | "NYC" | | {EXTERNAL LOCATION} | String | +| key_paths.swift:80:40:80:46 | "10001" | | {EXTERNAL LOCATION} | String | +| key_paths.swift:81:7:81:12 | person | | key_paths.swift:58:1:66:1 | Person | +| key_paths.swift:81:16:81:51 | Person(...) | | key_paths.swift:58:1:66:1 | Person | +| key_paths.swift:81:29:81:35 | "Alice" | | {EXTERNAL LOCATION} | String | +| key_paths.swift:81:47:81:50 | addr | | key_paths.swift:68:1:76:1 | Address | +| key_paths.swift:83:14:83:19 | person | | key_paths.swift:58:1:66:1 | Person | +| key_paths.swift:89:7:89:10 | name | | {EXTERNAL LOCATION} | String | +| key_paths.swift:90:7:90:12 | salary | | {EXTERNAL LOCATION} | Int | +| key_paths.swift:92:3:95:3 | Block | | {EXTERNAL LOCATION} | Int | +| key_paths.swift:92:8:92:11 | name | | {EXTERNAL LOCATION} | String | +| key_paths.swift:92:22:92:27 | salary | | {EXTERNAL LOCATION} | Int | +| key_paths.swift:93:5:93:8 | self | | key_paths.swift:88:1:96:1 | Employee | +| key_paths.swift:93:5:93:13 | ... .name | | {EXTERNAL LOCATION} | String | +| key_paths.swift:93:5:93:20 | ... = ... | | {EXTERNAL LOCATION} | String | +| key_paths.swift:93:17:93:20 | name | | {EXTERNAL LOCATION} | String | +| key_paths.swift:94:5:94:8 | self | | key_paths.swift:88:1:96:1 | Employee | +| key_paths.swift:94:5:94:15 | ... .salary | | {EXTERNAL LOCATION} | Int | +| key_paths.swift:94:5:94:24 | ... = ... | | {EXTERNAL LOCATION} | Int | +| key_paths.swift:94:19:94:24 | salary | | {EXTERNAL LOCATION} | Int | +| key_paths.swift:98:1:100:1 | Block | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:98:1:100:1 | Block | Element | key_paths.swift:98:22:98:22 | V | +| key_paths.swift:98:27:98:31 | items | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:98:27:98:31 | items | Element | key_paths.swift:98:19:98:20 | T | +| key_paths.swift:98:39:98:45 | keyPath | unknown type parameter 0 | key_paths.swift:98:19:98:20 | T | +| key_paths.swift:98:39:98:45 | keyPath | unknown type parameter 1 | key_paths.swift:98:22:98:22 | V | +| key_paths.swift:99:10:99:14 | items | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:99:10:99:14 | items | Element | key_paths.swift:98:19:98:20 | T | +| key_paths.swift:99:10:99:43 | ... .map(...) | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:99:10:99:43 | ... .map(...) | Element | key_paths.swift:98:22:98:22 | V | +| key_paths.swift:99:20:99:43 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| key_paths.swift:99:34:99:40 | keyPath | unknown type parameter 0 | key_paths.swift:98:19:98:20 | T | +| key_paths.swift:99:34:99:40 | keyPath | unknown type parameter 1 | key_paths.swift:98:22:98:22 | V | +| key_paths.swift:103:7:103:8 | e1 | | key_paths.swift:88:1:96:1 | Employee | +| key_paths.swift:103:12:103:47 | Employee(...) | | key_paths.swift:88:1:96:1 | Employee | +| key_paths.swift:103:27:103:33 | "Alice" | | {EXTERNAL LOCATION} | String | +| key_paths.swift:103:44:103:46 | 100 | | {EXTERNAL LOCATION} | Int | +| key_paths.swift:104:7:104:8 | e2 | | key_paths.swift:88:1:96:1 | Employee | +| key_paths.swift:104:12:104:45 | Employee(...) | | key_paths.swift:88:1:96:1 | Employee | +| key_paths.swift:104:27:104:31 | "Bob" | | {EXTERNAL LOCATION} | String | +| key_paths.swift:104:42:104:44 | 200 | | {EXTERNAL LOCATION} | Int | +| key_paths.swift:105:7:105:15 | employees | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:105:7:105:15 | employees | Element | key_paths.swift:88:1:96:1 | Employee | +| key_paths.swift:105:19:105:26 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:105:19:105:26 | ArrayLiteral | Element | key_paths.swift:88:1:96:1 | Employee | +| key_paths.swift:105:20:105:21 | e1 | | key_paths.swift:88:1:96:1 | Employee | +| key_paths.swift:105:24:105:25 | e2 | | key_paths.swift:88:1:96:1 | Employee | +| key_paths.swift:106:7:106:11 | names | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:106:15:106:54 | extractField(...) | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:106:28:106:36 | employees | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:106:28:106:36 | employees | Element | key_paths.swift:88:1:96:1 | Employee | +| key_paths.swift:107:14:107:18 | names | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:107:20:107:20 | 0 | | {EXTERNAL LOCATION} | Int | +| key_paths.swift:108:7:108:14 | salaries | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:108:18:108:59 | extractField(...) | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:108:31:108:39 | employees | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:108:31:108:39 | employees | Element | key_paths.swift:88:1:96:1 | Employee | +| key_paths.swift:109:16:109:23 | salaries | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:109:25:109:25 | 0 | | {EXTERNAL LOCATION} | Int | +| key_paths.swift:115:7:115:10 | item | | key_paths.swift:114:19:114:19 | T | +| key_paths.swift:117:3:119:3 | Block | | key_paths.swift:114:19:114:19 | T | +| key_paths.swift:117:8:117:11 | item | | key_paths.swift:114:19:114:19 | T | +| key_paths.swift:118:5:118:8 | self | | key_paths.swift:114:1:120:1 | KPContainer | +| key_paths.swift:118:5:118:8 | self | T | key_paths.swift:114:19:114:19 | T | +| key_paths.swift:118:5:118:13 | ... .item | | key_paths.swift:114:19:114:19 | T | +| key_paths.swift:118:5:118:20 | ... = ... | | key_paths.swift:114:19:114:19 | T | +| key_paths.swift:118:17:118:20 | item | | key_paths.swift:114:19:114:19 | T | +| key_paths.swift:124:7:124:7 | c | | key_paths.swift:114:1:120:1 | KPContainer | +| key_paths.swift:124:7:124:7 | c | T | {EXTERNAL LOCATION} | Int | +| key_paths.swift:124:11:124:31 | KPContainer(...) | | key_paths.swift:114:1:120:1 | KPContainer | +| key_paths.swift:124:11:124:31 | KPContainer(...) | T | {EXTERNAL LOCATION} | Int | +| key_paths.swift:124:29:124:30 | 42 | | {EXTERNAL LOCATION} | Int | +| key_paths.swift:125:11:125:11 | c | | key_paths.swift:114:1:120:1 | KPContainer | +| key_paths.swift:125:11:125:11 | c | T | {EXTERNAL LOCATION} | Int | +| key_paths.swift:131:7:131:7 | p | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:131:11:131:31 | Point(...) | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:133:3:133:3 | p | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:134:14:134:14 | p | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:144:7:144:7 | s | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:144:11:144:31 | Point(...) | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:145:7:145:7 | e | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:145:11:145:31 | Point(...) | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:146:7:146:10 | line | | key_paths.swift:17:1:25:1 | Line | +| key_paths.swift:146:14:146:35 | Line(...) | | key_paths.swift:17:1:25:1 | Line | +| key_paths.swift:146:26:146:26 | s | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:146:34:146:34 | e | | key_paths.swift:3:1:15:1 | Point | +| key_paths.swift:147:13:147:16 | line | | key_paths.swift:17:1:25:1 | Line | +| key_paths.swift:153:7:153:8 | e1 | | key_paths.swift:88:1:96:1 | Employee | +| key_paths.swift:153:12:153:47 | Employee(...) | | key_paths.swift:88:1:96:1 | Employee | +| key_paths.swift:153:27:153:33 | "Alice" | | {EXTERNAL LOCATION} | String | +| key_paths.swift:153:44:153:46 | 100 | | {EXTERNAL LOCATION} | Int | +| key_paths.swift:154:7:154:8 | e2 | | key_paths.swift:88:1:96:1 | Employee | +| key_paths.swift:154:12:154:45 | Employee(...) | | key_paths.swift:88:1:96:1 | Employee | +| key_paths.swift:154:27:154:31 | "Bob" | | {EXTERNAL LOCATION} | String | +| key_paths.swift:154:42:154:44 | 200 | | {EXTERNAL LOCATION} | Int | +| key_paths.swift:155:7:155:15 | employees | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:155:7:155:15 | employees | Element | key_paths.swift:88:1:96:1 | Employee | +| key_paths.swift:155:19:155:26 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:155:19:155:26 | ArrayLiteral | Element | key_paths.swift:88:1:96:1 | Employee | +| key_paths.swift:155:20:155:21 | e1 | | key_paths.swift:88:1:96:1 | Employee | +| key_paths.swift:155:24:155:25 | e2 | | key_paths.swift:88:1:96:1 | Employee | +| key_paths.swift:156:7:156:11 | names | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:156:15:156:23 | employees | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:156:15:156:23 | employees | Element | key_paths.swift:88:1:96:1 | Employee | +| key_paths.swift:156:15:156:35 | ... .map(...) | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:157:14:157:18 | names | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:157:20:157:20 | 0 | | {EXTERNAL LOCATION} | Int | +| key_paths.swift:158:7:158:14 | salaries | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:158:18:158:26 | employees | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:158:18:158:26 | employees | Element | key_paths.swift:88:1:96:1 | Employee | +| key_paths.swift:158:18:158:40 | ... .map(...) | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:159:16:159:23 | salaries | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:159:25:159:25 | 0 | | {EXTERNAL LOCATION} | Int | +| key_paths.swift:165:7:165:11 | color | | {EXTERNAL LOCATION} | String | +| key_paths.swift:167:3:169:3 | Block | | {EXTERNAL LOCATION} | String | +| key_paths.swift:167:8:167:12 | color | | {EXTERNAL LOCATION} | String | +| key_paths.swift:168:5:168:8 | self | | key_paths.swift:164:1:170:1 | Shape2 | +| key_paths.swift:168:5:168:14 | ... .color | | {EXTERNAL LOCATION} | String | +| key_paths.swift:168:5:168:22 | ... = ... | | {EXTERNAL LOCATION} | String | +| key_paths.swift:168:18:168:22 | color | | {EXTERNAL LOCATION} | String | +| key_paths.swift:173:7:173:12 | radius | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:175:3:178:3 | Block | | key_paths.swift:164:1:170:1 | Shape2 | +| key_paths.swift:175:8:175:12 | color | | {EXTERNAL LOCATION} | String | +| key_paths.swift:175:23:175:28 | radius | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:176:5:176:8 | self | | key_paths.swift:172:1:179:1 | Circle2 | +| key_paths.swift:176:5:176:15 | ... .radius | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:176:5:176:24 | ... = ... | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:176:19:176:24 | radius | | {EXTERNAL LOCATION} | Double | +| key_paths.swift:177:5:177:9 | super | | key_paths.swift:164:1:170:1 | Shape2 | +| key_paths.swift:177:5:177:28 | ... .init(...) | | key_paths.swift:164:1:170:1 | Shape2 | +| key_paths.swift:177:23:177:27 | color | | {EXTERNAL LOCATION} | String | +| key_paths.swift:185:7:185:7 | c | | key_paths.swift:172:1:179:1 | Circle2 | +| key_paths.swift:185:11:185:44 | Circle2(...) | | key_paths.swift:172:1:179:1 | Circle2 | +| key_paths.swift:185:26:185:30 | "red" | | {EXTERNAL LOCATION} | String | +| key_paths.swift:186:13:186:13 | c | | key_paths.swift:172:1:179:1 | Circle2 | +| key_paths.swift:187:13:187:13 | c | | key_paths.swift:172:1:179:1 | Circle2 | +| key_paths.swift:195:16:195:17 | 42 | | {EXTERNAL LOCATION} | Int | +| key_paths.swift:195:20:195:26 | "hello" | | {EXTERNAL LOCATION} | String | +| key_paths.swift:204:7:204:9 | arr | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:204:7:204:9 | arr | Element | {EXTERNAL LOCATION} | Int | +| key_paths.swift:204:13:204:24 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:204:13:204:24 | ArrayLiteral | Element | {EXTERNAL LOCATION} | Int | +| key_paths.swift:204:14:204:15 | 10 | | {EXTERNAL LOCATION} | Int | +| key_paths.swift:204:18:204:19 | 20 | | {EXTERNAL LOCATION} | Int | +| key_paths.swift:204:22:204:23 | 30 | | {EXTERNAL LOCATION} | Int | +| key_paths.swift:205:15:205:17 | arr | | {EXTERNAL LOCATION} | Array | +| key_paths.swift:205:15:205:17 | arr | Element | {EXTERNAL LOCATION} | Int | +| lub.swift:12:7:12:7 | b | | lub.swift:5:1:7:1 | B | +| lub.swift:12:11:12:13 | B(...) | | lub.swift:5:1:7:1 | B | +| lub.swift:14:7:14:7 | x | | lub.swift:5:1:7:1 | B | +| lub.swift:14:11:14:11 | 2 | | {EXTERNAL LOCATION} | Int | +| lub.swift:14:11:14:15 | ... > ... | | {EXTERNAL LOCATION} | Int | +| lub.swift:14:11:14:23 | IfExpr | | lub.swift:5:1:7:1 | B | +| lub.swift:14:15:14:15 | 3 | | {EXTERNAL LOCATION} | Int | +| lub.swift:14:19:14:19 | b | | lub.swift:5:1:7:1 | B | +| overload_resolution.swift:6:3:8:3 | Block | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:6:17:6:17 | x | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:7:12:7:16 | "int" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:10:3:12:3 | Block | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:10:17:10:17 | x | | {EXTERNAL LOCATION} | Double | +| overload_resolution.swift:11:12:11:19 | "double" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:14:3:16:3 | Block | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:14:17:14:17 | x | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:15:12:15:19 | "string" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:18:3:20:3 | Block | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:18:17:18:17 | x | | {EXTERNAL LOCATION} | Bool | +| overload_resolution.swift:19:12:19:17 | "bool" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:24:7:24:7 | o | | overload_resolution.swift:3:1:21:1 | OverloadByType | +| overload_resolution.swift:24:11:24:26 | OverloadByType(...) | | overload_resolution.swift:3:1:21:1 | OverloadByType | +| overload_resolution.swift:25:7:25:8 | r1 | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:25:12:25:12 | o | | overload_resolution.swift:3:1:21:1 | OverloadByType | +| overload_resolution.swift:25:12:25:23 | ... .handle(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:25:21:25:22 | 42 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:26:7:26:8 | r2 | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:26:12:26:12 | o | | overload_resolution.swift:3:1:21:1 | OverloadByType | +| overload_resolution.swift:26:12:26:25 | ... .handle(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:27:7:27:8 | r3 | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:27:12:27:12 | o | | overload_resolution.swift:3:1:21:1 | OverloadByType | +| overload_resolution.swift:27:12:27:25 | ... .handle(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:27:21:27:24 | "hi" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:28:7:28:8 | r4 | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:28:12:28:12 | o | | overload_resolution.swift:3:1:21:1 | OverloadByType | +| overload_resolution.swift:28:12:28:25 | ... .handle(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:28:21:28:24 | true | | {EXTERNAL LOCATION} | Bool | +| overload_resolution.swift:36:3:38:3 | Block | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:36:18:36:22 | width | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:37:12:37:18 | "width" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:40:3:42:3 | Block | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:40:18:40:23 | height | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:41:12:41:19 | "height" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:44:3:46:3 | Block | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:44:18:44:22 | width | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:44:30:44:35 | height | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:45:12:45:17 | "both" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:48:3:50:3 | Block | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:48:18:48:21 | size | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:49:12:49:17 | "size" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:54:7:54:7 | o | | overload_resolution.swift:33:1:51:1 | OverloadByLabel | +| overload_resolution.swift:54:11:54:27 | OverloadByLabel(...) | | overload_resolution.swift:33:1:51:1 | OverloadByLabel | +| overload_resolution.swift:55:7:55:8 | r1 | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:55:12:55:12 | o | | overload_resolution.swift:33:1:51:1 | OverloadByLabel | +| overload_resolution.swift:55:12:55:33 | ... .configure(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:55:31:55:32 | 10 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:56:7:56:8 | r2 | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:56:12:56:12 | o | | overload_resolution.swift:33:1:51:1 | OverloadByLabel | +| overload_resolution.swift:56:12:56:34 | ... .configure(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:56:32:56:33 | 20 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:57:7:57:8 | r3 | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:57:12:57:12 | o | | overload_resolution.swift:33:1:51:1 | OverloadByLabel | +| overload_resolution.swift:57:12:57:45 | ... .configure(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:57:31:57:32 | 10 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:57:43:57:44 | 20 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:58:7:58:8 | r4 | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:58:12:58:12 | o | | overload_resolution.swift:33:1:51:1 | OverloadByLabel | +| overload_resolution.swift:58:12:58:32 | ... .configure(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:58:30:58:31 | 30 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:66:3:68:3 | Block | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:67:12:67:12 | 0 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:70:3:72:3 | Block | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:70:18:70:18 | x | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:71:12:71:12 | x | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:74:3:76:3 | Block | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:74:18:74:18 | x | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:74:28:74:28 | y | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:75:12:75:12 | x | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:75:12:75:16 | ... + ... | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:75:16:75:16 | y | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:78:3:80:3 | Block | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:78:18:78:18 | x | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:78:28:78:28 | y | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:78:38:78:38 | z | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:79:12:79:12 | x | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:79:12:79:16 | ... + ... | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:79:12:79:20 | ... + ... | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:79:16:79:16 | y | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:79:20:79:20 | z | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:84:7:84:7 | o | | overload_resolution.swift:63:1:81:1 | OverloadByArity | +| overload_resolution.swift:84:11:84:27 | OverloadByArity(...) | | overload_resolution.swift:63:1:81:1 | OverloadByArity | +| overload_resolution.swift:85:7:85:8 | r0 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:85:12:85:12 | o | | overload_resolution.swift:63:1:81:1 | OverloadByArity | +| overload_resolution.swift:85:12:85:22 | ... .compute(...) | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:86:7:86:8 | r1 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:86:12:86:12 | o | | overload_resolution.swift:63:1:81:1 | OverloadByArity | +| overload_resolution.swift:86:12:86:23 | ... .compute(...) | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:86:22:86:22 | 1 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:87:7:87:8 | r2 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:87:12:87:12 | o | | overload_resolution.swift:63:1:81:1 | OverloadByArity | +| overload_resolution.swift:87:12:87:26 | ... .compute(...) | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:87:22:87:22 | 1 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:87:25:87:25 | 2 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:88:7:88:8 | r3 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:88:12:88:12 | o | | overload_resolution.swift:63:1:81:1 | OverloadByArity | +| overload_resolution.swift:88:12:88:29 | ... .compute(...) | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:88:22:88:22 | 1 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:88:25:88:25 | 2 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:88:28:88:28 | 3 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:96:3:98:3 | Block | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:97:12:97:12 | 0 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:100:3:102:3 | Block | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:101:12:101:13 | "" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:110:7:110:7 | o | | overload_resolution.swift:93:1:107:1 | OverloadByReturn | +| overload_resolution.swift:110:11:110:28 | OverloadByReturn(...) | | overload_resolution.swift:93:1:107:1 | OverloadByReturn | +| overload_resolution.swift:111:7:111:8 | r1 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:111:17:111:17 | o | | overload_resolution.swift:93:1:107:1 | OverloadByReturn | +| overload_resolution.swift:111:17:111:26 | ... .create(...) | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:111:17:111:26 | ... .create(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:111:17:111:26 | ... .create(...) | | {EXTERNAL LOCATION} | Double | +| overload_resolution.swift:112:7:112:8 | r2 | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:112:20:112:20 | o | | overload_resolution.swift:93:1:107:1 | OverloadByReturn | +| overload_resolution.swift:112:20:112:29 | ... .create(...) | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:112:20:112:29 | ... .create(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:112:20:112:29 | ... .create(...) | | {EXTERNAL LOCATION} | Double | +| overload_resolution.swift:113:7:113:8 | r3 | | {EXTERNAL LOCATION} | Double | +| overload_resolution.swift:113:20:113:20 | o | | overload_resolution.swift:93:1:107:1 | OverloadByReturn | +| overload_resolution.swift:113:20:113:29 | ... .create(...) | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:113:20:113:29 | ... .create(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:113:20:113:29 | ... .create(...) | | {EXTERNAL LOCATION} | Double | +| overload_resolution.swift:121:3:123:3 | Block | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:121:18:121:18 | x | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:122:12:122:21 | "concrete" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:125:3:127:3 | Block | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:125:21:125:21 | x | | overload_resolution.swift:125:16:125:16 | T | +| overload_resolution.swift:126:12:126:20 | "generic" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:131:7:131:7 | o | | overload_resolution.swift:118:1:128:1 | OverloadGenericVsConcrete | +| overload_resolution.swift:131:11:131:37 | OverloadGenericVsConcrete(...) | | overload_resolution.swift:118:1:128:1 | OverloadGenericVsConcrete | +| overload_resolution.swift:132:7:132:8 | r1 | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:132:12:132:12 | o | | overload_resolution.swift:118:1:128:1 | OverloadGenericVsConcrete | +| overload_resolution.swift:132:12:132:24 | ... .process(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:132:22:132:23 | 42 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:133:7:133:8 | r2 | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:133:12:133:12 | o | | overload_resolution.swift:118:1:128:1 | OverloadGenericVsConcrete | +| overload_resolution.swift:133:12:133:29 | ... .process(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:133:22:133:28 | "hello" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:134:7:134:8 | r3 | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:134:12:134:12 | o | | overload_resolution.swift:118:1:128:1 | OverloadGenericVsConcrete | +| overload_resolution.swift:134:12:134:26 | ... .process(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:134:22:134:25 | true | | {EXTERNAL LOCATION} | Bool | +| overload_resolution.swift:139:1:141:1 | Block | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:139:21:139:21 | x | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:140:10:140:14 | "int" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:143:1:145:1 | Block | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:143:21:143:21 | x | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:144:10:144:17 | "string" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:147:1:149:1 | Block | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:147:21:147:21 | x | | {EXTERNAL LOCATION} | Double | +| overload_resolution.swift:148:10:148:17 | "double" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:152:7:152:8 | r1 | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:152:12:152:27 | freeOverload(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:152:25:152:26 | 42 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:153:7:153:8 | r2 | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:153:12:153:29 | freeOverload(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:153:25:153:28 | "hi" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:154:7:154:8 | r3 | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:154:12:154:28 | freeOverload(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:160:7:160:11 | value | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:162:3:164:3 | Block | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:163:5:163:9 | value | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:163:5:163:21 | ... = ... | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:163:13:163:21 | "default" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:166:3:168:3 | Block | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:166:8:166:10 | int | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:167:5:167:9 | value | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:167:5:167:17 | ... = ... | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:167:13:167:17 | "int" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:170:3:172:3 | Block | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:170:8:170:10 | str | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:171:5:171:9 | value | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:171:5:171:15 | ... = ... | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:171:13:171:15 | str | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:174:3:176:3 | Block | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:174:8:174:8 | x | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:174:16:174:16 | y | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:175:5:175:9 | value | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:175:5:175:18 | ... = ... | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:175:13:175:18 | "pair" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:178:3:180:3 | Block | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:179:12:179:16 | value | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:184:7:184:8 | m1 | | overload_resolution.swift:159:1:181:1 | MultiInit | +| overload_resolution.swift:184:12:184:22 | MultiInit(...) | | overload_resolution.swift:159:1:181:1 | MultiInit | +| overload_resolution.swift:185:7:185:8 | m2 | | overload_resolution.swift:159:1:181:1 | MultiInit | +| overload_resolution.swift:185:12:185:28 | MultiInit(...) | | overload_resolution.swift:159:1:181:1 | MultiInit | +| overload_resolution.swift:185:27:185:27 | 5 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:186:7:186:8 | m3 | | overload_resolution.swift:159:1:181:1 | MultiInit | +| overload_resolution.swift:186:12:186:30 | MultiInit(...) | | overload_resolution.swift:159:1:181:1 | MultiInit | +| overload_resolution.swift:186:27:186:29 | "x" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:187:7:187:8 | m4 | | overload_resolution.swift:159:1:181:1 | MultiInit | +| overload_resolution.swift:187:12:187:32 | MultiInit(...) | | overload_resolution.swift:159:1:181:1 | MultiInit | +| overload_resolution.swift:187:25:187:25 | 1 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:187:31:187:31 | 2 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:188:7:188:7 | v | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:188:11:188:12 | m1 | | overload_resolution.swift:159:1:181:1 | MultiInit | +| overload_resolution.swift:188:11:188:23 | ... .getValue(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:194:3:196:3 | Block | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:195:12:195:21 | "instance" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:198:3:200:3 | Block | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:199:12:199:19 | "static" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:206:7:206:7 | o | | overload_resolution.swift:193:1:203:1 | StaticVsInstance | +| overload_resolution.swift:206:11:206:28 | StaticVsInstance(...) | | overload_resolution.swift:193:1:203:1 | StaticVsInstance | +| overload_resolution.swift:207:7:207:8 | r1 | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:207:12:207:12 | o | | overload_resolution.swift:193:1:203:1 | StaticVsInstance | +| overload_resolution.swift:207:12:207:21 | ... .action(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:208:7:208:8 | r2 | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:208:12:208:36 | ... .action(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:218:3:220:3 | Block | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:219:12:219:20 | "default" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:222:3:224:3 | Block | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:223:12:223:18 | "extra" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:230:3:232:3 | Block | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:231:12:231:21 | "concrete" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:236:7:236:7 | d | | overload_resolution.swift:227:1:233:1 | DescribableImpl | +| overload_resolution.swift:236:11:236:27 | DescribableImpl(...) | | overload_resolution.swift:227:1:233:1 | DescribableImpl | +| overload_resolution.swift:237:7:237:8 | r1 | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:237:12:237:12 | d | | overload_resolution.swift:227:1:233:1 | DescribableImpl | +| overload_resolution.swift:237:12:237:23 | ... .describe(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:238:7:238:8 | r2 | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:238:12:238:12 | d | | overload_resolution.swift:227:1:233:1 | DescribableImpl | +| overload_resolution.swift:238:12:238:20 | ... .extra(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:246:3:248:3 | Block | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:247:12:247:17 | "base" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:250:3:252:3 | Block | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:251:12:251:21 | "baseOnly" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:256:3:258:3 | Block | | overload_resolution.swift:243:1:253:1 | Base | +| overload_resolution.swift:257:5:257:9 | super | | overload_resolution.swift:243:1:253:1 | Base | +| overload_resolution.swift:257:5:257:16 | ... .init(...) | | overload_resolution.swift:243:1:253:1 | Base | +| overload_resolution.swift:260:3:262:3 | Block | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:261:12:261:16 | "sub" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:264:3:266:3 | Block | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:265:12:265:20 | "subOnly" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:270:3:272:3 | Block | | overload_resolution.swift:255:1:267:1 | Sub | +| overload_resolution.swift:271:5:271:9 | super | | overload_resolution.swift:255:1:267:1 | Sub | +| overload_resolution.swift:271:5:271:16 | ... .init(...) | | overload_resolution.swift:255:1:267:1 | Sub | +| overload_resolution.swift:274:3:276:3 | Block | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:275:12:275:19 | "subsub" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:280:7:280:7 | b | | overload_resolution.swift:243:1:253:1 | Base | +| overload_resolution.swift:280:11:280:16 | Base(...) | | overload_resolution.swift:243:1:253:1 | Base | +| overload_resolution.swift:281:7:281:8 | rb | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:281:12:281:12 | b | | overload_resolution.swift:243:1:253:1 | Base | +| overload_resolution.swift:281:12:281:21 | ... .action(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:283:7:283:7 | s | | overload_resolution.swift:255:1:267:1 | Sub | +| overload_resolution.swift:283:11:283:15 | Sub(...) | | overload_resolution.swift:255:1:267:1 | Sub | +| overload_resolution.swift:284:7:284:8 | rs | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:284:12:284:12 | s | | overload_resolution.swift:255:1:267:1 | Sub | +| overload_resolution.swift:284:12:284:21 | ... .action(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:285:7:285:9 | rbo | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:285:13:285:13 | s | | overload_resolution.swift:255:1:267:1 | Sub | +| overload_resolution.swift:285:13:285:24 | ... .baseOnly(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:286:7:286:9 | rso | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:286:13:286:13 | s | | overload_resolution.swift:255:1:267:1 | Sub | +| overload_resolution.swift:286:13:286:23 | ... .subOnly(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:288:7:288:8 | ss | | overload_resolution.swift:269:1:277:1 | SubSub | +| overload_resolution.swift:288:12:288:19 | SubSub(...) | | overload_resolution.swift:269:1:277:1 | SubSub | +| overload_resolution.swift:289:7:289:9 | rss | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:289:13:289:14 | ss | | overload_resolution.swift:269:1:277:1 | SubSub | +| overload_resolution.swift:289:13:289:23 | ... .action(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:290:7:290:10 | rbo2 | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:290:14:290:15 | ss | | overload_resolution.swift:269:1:277:1 | SubSub | +| overload_resolution.swift:290:14:290:26 | ... .baseOnly(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:291:7:291:10 | rso2 | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:291:14:291:15 | ss | | overload_resolution.swift:269:1:277:1 | SubSub | +| overload_resolution.swift:291:14:291:25 | ... .subOnly(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:299:3:301:3 | Block | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:299:16:299:21 | target | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:300:12:300:17 | target | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:303:3:305:3 | Block | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:303:18:303:23 | source | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:304:12:304:17 | source | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:307:3:309:3 | Block | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:307:16:307:21 | target | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:307:37:307:42 | source | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:308:12:308:17 | target | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:308:12:308:26 | ... + ... | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:308:21:308:26 | source | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:313:7:313:7 | o | | overload_resolution.swift:296:1:310:1 | LabelVariants | +| overload_resolution.swift:313:11:313:25 | LabelVariants(...) | | overload_resolution.swift:296:1:310:1 | LabelVariants | +| overload_resolution.swift:314:7:314:8 | r1 | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:314:12:314:12 | o | | overload_resolution.swift:296:1:310:1 | LabelVariants | +| overload_resolution.swift:314:12:314:26 | ... .send(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:314:23:314:25 | "x" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:315:7:315:8 | r2 | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:315:12:315:12 | o | | overload_resolution.swift:296:1:310:1 | LabelVariants | +| overload_resolution.swift:315:12:315:28 | ... .send(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:315:25:315:27 | "y" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:316:7:316:8 | r3 | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:316:12:316:12 | o | | overload_resolution.swift:296:1:310:1 | LabelVariants | +| overload_resolution.swift:316:12:316:37 | ... .send(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:316:23:316:25 | "x" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:316:34:316:36 | "y" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:326:3:326:40 | Block | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:326:38:326:38 | 0 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:333:1:335:1 | Block | | overload_resolution.swift:333:20:333:30 | T | +| overload_resolution.swift:333:35:333:35 | x | | overload_resolution.swift:333:20:333:30 | T | +| overload_resolution.swift:334:10:334:10 | x | | overload_resolution.swift:333:20:333:30 | T | +| overload_resolution.swift:337:1:339:1 | Block | | overload_resolution.swift:337:20:337:31 | T | +| overload_resolution.swift:337:36:337:36 | x | | overload_resolution.swift:337:20:337:31 | T | +| overload_resolution.swift:338:10:338:10 | x | | overload_resolution.swift:337:20:337:31 | T | +| overload_resolution.swift:342:7:342:8 | r1 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:342:12:342:28 | constrainedId(...) | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:342:26:342:27 | 42 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:343:7:343:8 | r2 | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:343:12:343:33 | constrainedId(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:343:26:343:32 | "hello" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:349:7:349:10 | item | | overload_resolution.swift:348:11:348:11 | T | +| overload_resolution.swift:351:3:353:3 | Block | | overload_resolution.swift:348:11:348:11 | T | +| overload_resolution.swift:351:10:351:13 | item | | overload_resolution.swift:348:11:348:11 | T | +| overload_resolution.swift:352:5:352:8 | self | | overload_resolution.swift:348:1:362:1 | Box | +| overload_resolution.swift:352:5:352:8 | self | T | overload_resolution.swift:348:11:348:11 | T | +| overload_resolution.swift:352:5:352:13 | ... .item | | overload_resolution.swift:348:11:348:11 | T | +| overload_resolution.swift:352:5:352:20 | ... = ... | | overload_resolution.swift:348:11:348:11 | T | +| overload_resolution.swift:352:17:352:20 | item | | overload_resolution.swift:348:11:348:11 | T | +| overload_resolution.swift:355:3:357:3 | Block | | overload_resolution.swift:348:11:348:11 | T | +| overload_resolution.swift:356:12:356:15 | item | | overload_resolution.swift:348:11:348:11 | T | +| overload_resolution.swift:359:3:361:3 | Block | | overload_resolution.swift:348:11:348:11 | T | +| overload_resolution.swift:359:18:359:24 | newItem | | overload_resolution.swift:348:11:348:11 | T | +| overload_resolution.swift:360:5:360:8 | item | | overload_resolution.swift:348:11:348:11 | T | +| overload_resolution.swift:360:5:360:18 | ... = ... | | overload_resolution.swift:348:11:348:11 | T | +| overload_resolution.swift:360:12:360:18 | newItem | | overload_resolution.swift:348:11:348:11 | T | +| overload_resolution.swift:365:7:365:12 | intBox | | overload_resolution.swift:348:1:362:1 | Box | +| overload_resolution.swift:365:7:365:12 | intBox | T | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:365:16:365:22 | Box(...) | | overload_resolution.swift:348:1:362:1 | Box | +| overload_resolution.swift:365:16:365:22 | Box(...) | T | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:365:20:365:21 | 10 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:366:7:366:12 | strBox | | overload_resolution.swift:348:1:362:1 | Box | +| overload_resolution.swift:366:7:366:12 | strBox | T | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:366:16:366:24 | Box(...) | | overload_resolution.swift:348:1:362:1 | Box | +| overload_resolution.swift:366:16:366:24 | Box(...) | T | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:366:20:366:23 | "hi" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:367:7:367:8 | v1 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:367:12:367:17 | intBox | | overload_resolution.swift:348:1:362:1 | Box | +| overload_resolution.swift:367:12:367:17 | intBox | T | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:367:12:367:23 | ... .get(...) | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:368:7:368:8 | v2 | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:368:12:368:17 | strBox | | overload_resolution.swift:348:1:362:1 | Box | +| overload_resolution.swift:368:12:368:17 | strBox | T | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:368:12:368:23 | ... .get(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:369:3:369:8 | intBox | | overload_resolution.swift:348:1:362:1 | Box | +| overload_resolution.swift:369:3:369:8 | intBox | T | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:369:18:369:19 | 20 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:370:3:370:8 | strBox | | overload_resolution.swift:348:1:362:1 | Box | +| overload_resolution.swift:370:3:370:8 | strBox | T | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:370:18:370:22 | "bye" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:376:7:376:10 | name | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:377:7:377:10 | size | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:379:3:382:3 | Block | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:379:8:379:11 | name | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:379:22:379:25 | size | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:380:5:380:8 | self | | overload_resolution.swift:375:1:391:1 | Widget | +| overload_resolution.swift:380:5:380:13 | ... .name | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:380:5:380:20 | ... = ... | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:380:17:380:20 | name | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:381:5:381:8 | self | | overload_resolution.swift:375:1:391:1 | Widget | +| overload_resolution.swift:381:5:381:13 | ... .size | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:381:5:381:20 | ... = ... | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:381:17:381:20 | size | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:384:3:386:3 | Block | | overload_resolution.swift:375:1:391:1 | Widget | +| overload_resolution.swift:384:20:384:23 | name | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:385:5:385:8 | self | | overload_resolution.swift:375:1:391:1 | Widget | +| overload_resolution.swift:385:5:385:34 | ... .init(...) | | overload_resolution.swift:375:1:391:1 | Widget | +| overload_resolution.swift:385:21:385:24 | name | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:385:33:385:33 | 1 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:388:3:390:3 | Block | | overload_resolution.swift:375:1:391:1 | Widget | +| overload_resolution.swift:388:20:388:23 | size | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:389:5:389:8 | self | | overload_resolution.swift:375:1:391:1 | Widget | +| overload_resolution.swift:389:5:389:42 | ... .init(...) | | overload_resolution.swift:375:1:391:1 | Widget | +| overload_resolution.swift:389:21:389:29 | "default" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:389:38:389:41 | size | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:394:7:394:8 | w1 | | overload_resolution.swift:375:1:391:1 | Widget | +| overload_resolution.swift:394:12:394:37 | Widget(...) | | overload_resolution.swift:375:1:391:1 | Widget | +| overload_resolution.swift:394:25:394:27 | "a" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:394:36:394:36 | 5 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:395:7:395:8 | w2 | | overload_resolution.swift:375:1:391:1 | Widget | +| overload_resolution.swift:395:12:395:28 | Widget(...) | | overload_resolution.swift:375:1:391:1 | Widget | +| overload_resolution.swift:395:25:395:27 | "b" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:396:7:396:8 | w3 | | overload_resolution.swift:375:1:391:1 | Widget | +| overload_resolution.swift:396:12:396:27 | Widget(...) | | overload_resolution.swift:375:1:391:1 | Widget | +| overload_resolution.swift:396:25:396:26 | 10 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:404:3:406:3 | Block | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:404:16:404:16 | f | | {EXTERNAL LOCATION} | Function | +| overload_resolution.swift:404:16:404:16 | f | Args | {EXTERNAL LOCATION} | Tuple1 | +| overload_resolution.swift:404:16:404:16 | f | Args.T0 | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:404:16:404:16 | f | Return | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:404:19:404:30 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| overload_resolution.swift:404:19:404:30 | FunctionExpr | Return | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:405:12:405:12 | f | | {EXTERNAL LOCATION} | Function | +| overload_resolution.swift:405:12:405:12 | f | Args | {EXTERNAL LOCATION} | Tuple1 | +| overload_resolution.swift:405:12:405:12 | f | Args.T0 | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:405:12:405:12 | f | Return | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:405:12:405:15 | f(...) | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:405:14:405:14 | 0 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:408:3:410:3 | Block | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:408:16:408:16 | f | | {EXTERNAL LOCATION} | Function | +| overload_resolution.swift:408:16:408:16 | f | Args | {EXTERNAL LOCATION} | Tuple1 | +| overload_resolution.swift:408:16:408:16 | f | Args.T0 | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:408:16:408:16 | f | Return | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:408:19:408:36 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| overload_resolution.swift:408:19:408:36 | FunctionExpr | Return | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:409:12:409:12 | f | | {EXTERNAL LOCATION} | Function | +| overload_resolution.swift:409:12:409:12 | f | Args | {EXTERNAL LOCATION} | Tuple1 | +| overload_resolution.swift:409:12:409:12 | f | Args.T0 | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:409:12:409:12 | f | Return | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:409:12:409:16 | f(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:409:14:409:15 | "" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:412:3:414:3 | Block | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:412:16:412:16 | f | | {EXTERNAL LOCATION} | Function | +| overload_resolution.swift:412:16:412:16 | f | Args | {EXTERNAL LOCATION} | Tuple2 | +| overload_resolution.swift:412:16:412:16 | f | Args.T0 | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:412:16:412:16 | f | Args.T1 | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:412:16:412:16 | f | Return | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:412:19:412:35 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| overload_resolution.swift:412:19:412:35 | FunctionExpr | Return | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:413:12:413:12 | f | | {EXTERNAL LOCATION} | Function | +| overload_resolution.swift:413:12:413:12 | f | Args | {EXTERNAL LOCATION} | Tuple2 | +| overload_resolution.swift:413:12:413:12 | f | Args.T0 | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:413:12:413:12 | f | Args.T1 | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:413:12:413:12 | f | Return | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:413:12:413:18 | f(...) | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:413:14:413:14 | 0 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:413:17:413:17 | 0 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:418:7:418:7 | p | | overload_resolution.swift:401:1:415:1 | Processor | +| overload_resolution.swift:418:11:418:21 | Processor(...) | | overload_resolution.swift:401:1:415:1 | Processor | +| overload_resolution.swift:419:7:419:8 | r1 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:419:7:419:8 | r1 | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:419:12:419:12 | p | | overload_resolution.swift:401:1:415:1 | Processor | +| overload_resolution.swift:419:12:419:34 | ... .apply(...) | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:419:12:419:34 | ... .apply(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:419:20:419:33 | Block | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:419:20:419:33 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| overload_resolution.swift:419:20:419:33 | FunctionExpr | Args | {EXTERNAL LOCATION} | Tuple1 | +| overload_resolution.swift:419:20:419:33 | FunctionExpr | Args.T0 | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:419:20:419:33 | FunctionExpr | Args.T0 | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:419:20:419:33 | FunctionExpr | Return | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:419:22:419:22 | x | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:419:22:419:22 | x | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:419:27:419:27 | x | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:419:27:419:27 | x | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:419:27:419:31 | ... + ... | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:419:31:419:31 | 1 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:420:7:420:8 | r2 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:420:7:420:8 | r2 | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:420:12:420:12 | p | | overload_resolution.swift:401:1:415:1 | Processor | +| overload_resolution.swift:420:12:420:36 | ... .apply(...) | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:420:12:420:36 | ... .apply(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:420:20:420:35 | Block | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:420:20:420:35 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| overload_resolution.swift:420:20:420:35 | FunctionExpr | Args | {EXTERNAL LOCATION} | Tuple1 | +| overload_resolution.swift:420:20:420:35 | FunctionExpr | Args.T0 | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:420:20:420:35 | FunctionExpr | Args.T0 | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:420:20:420:35 | FunctionExpr | Return | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:420:22:420:22 | s | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:420:22:420:22 | s | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:420:27:420:27 | s | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:420:27:420:27 | s | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:420:27:420:33 | ... + ... | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:420:31:420:33 | "!" | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:421:7:421:8 | r3 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:421:7:421:8 | r3 | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:421:12:421:12 | p | | overload_resolution.swift:401:1:415:1 | Processor | +| overload_resolution.swift:421:12:421:37 | ... .apply(...) | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:421:12:421:37 | ... .apply(...) | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:421:20:421:36 | Block | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:421:20:421:36 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| overload_resolution.swift:421:20:421:36 | FunctionExpr | Args | {EXTERNAL LOCATION} | Tuple2 | +| overload_resolution.swift:421:20:421:36 | FunctionExpr | Args.T0 | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:421:20:421:36 | FunctionExpr | Args.T1 | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:421:20:421:36 | FunctionExpr | Return | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:421:22:421:22 | x | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:421:25:421:25 | y | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:421:30:421:30 | x | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:421:30:421:34 | ... + ... | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:421:34:421:34 | y | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:427:7:427:10 | data | | {EXTERNAL LOCATION} | Array | +| overload_resolution.swift:427:7:427:10 | data | Element | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:427:21:427:29 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | +| overload_resolution.swift:427:21:427:29 | ArrayLiteral | Element | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:427:22:427:22 | 1 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:427:25:427:25 | 2 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:427:28:427:28 | 3 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:428:7:428:10 | dict | | {EXTERNAL LOCATION} | Dictionary | +| overload_resolution.swift:428:7:428:10 | dict | Key | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:428:7:428:10 | dict | Value | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:432:14:432:18 | index | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:433:12:433:15 | data | | {EXTERNAL LOCATION} | Array | +| overload_resolution.swift:433:12:433:15 | data | Element | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:433:17:433:21 | index | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:436:14:436:16 | key | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:437:12:437:15 | dict | | {EXTERNAL LOCATION} | Dictionary | +| overload_resolution.swift:437:12:437:15 | dict | Key | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:437:12:437:15 | dict | Value | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:437:17:437:19 | key | | {EXTERNAL LOCATION} | String | +| overload_resolution.swift:437:25:437:25 | 0 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:442:7:442:8 | ms | | overload_resolution.swift:426:1:439:1 | MultiSubscript | +| overload_resolution.swift:442:12:442:27 | MultiSubscript(...) | | overload_resolution.swift:426:1:439:1 | MultiSubscript | +| overload_resolution.swift:443:7:443:8 | r1 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:443:12:443:13 | ms | | overload_resolution.swift:426:1:439:1 | MultiSubscript | +| overload_resolution.swift:443:12:443:20 | ... .get(...) | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:443:19:443:19 | 0 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:444:7:444:8 | r2 | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:444:12:444:13 | ms | | overload_resolution.swift:426:1:439:1 | MultiSubscript | +| overload_resolution.swift:444:12:444:22 | ... .get(...) | | {EXTERNAL LOCATION} | Int | +| overload_resolution.swift:444:19:444:21 | "a" | | {EXTERNAL LOCATION} | String | +| pattern_matching.swift:1:26:1:29 | pair | | {EXTERNAL LOCATION} | Tuple2 | +| pattern_matching.swift:1:26:1:29 | pair | T0 | {EXTERNAL LOCATION} | Int | +| pattern_matching.swift:1:26:1:29 | pair | T1 | {EXTERNAL LOCATION} | String | +| pattern_matching.swift:2:7:2:20 | TupleExpr | | {EXTERNAL LOCATION} | Tuple2 | +| pattern_matching.swift:2:7:2:20 | TupleExpr | T0 | {EXTERNAL LOCATION} | Int | +| pattern_matching.swift:2:7:2:20 | TupleExpr | T1 | {EXTERNAL LOCATION} | String | +| pattern_matching.swift:2:24:2:27 | pair | | {EXTERNAL LOCATION} | Tuple2 | +| pattern_matching.swift:2:24:2:27 | pair | T0 | {EXTERNAL LOCATION} | Int | +| pattern_matching.swift:2:24:2:27 | pair | T1 | {EXTERNAL LOCATION} | String | +| pattern_matching.swift:8:8:8:14 | novalue | | pattern_matching.swift:7:1:11:1 | PatternMatch | +| pattern_matching.swift:8:8:8:14 | novalue | T | pattern_matching.swift:7:19:7:19 | T | +| pattern_matching.swift:13:30:13:34 | input | | pattern_matching.swift:7:1:11:1 | PatternMatch | +| pattern_matching.swift:13:30:13:34 | input | T | pattern_matching.swift:13:25:13:25 | T | +| pattern_matching.swift:14:10:14:14 | input | | pattern_matching.swift:7:1:11:1 | PatternMatch | +| pattern_matching.swift:14:10:14:14 | input | T | pattern_matching.swift:13:25:13:25 | T | +| pattern_matching.swift:15:8:15:15 | ... .novalue | | pattern_matching.swift:7:1:11:1 | PatternMatch | +| pattern_matching.swift:15:8:15:15 | ... .novalue | T | pattern_matching.swift:13:25:13:25 | T | +| pattern_matching.swift:17:8:17:24 | ... .value(...) | | pattern_matching.swift:7:1:11:1 | PatternMatch | +| pattern_matching.swift:17:8:17:24 | ... .value(...) | T | pattern_matching.swift:13:25:13:25 | T | +| pattern_matching.swift:19:8:19:52 | ... .nested(...) | | pattern_matching.swift:7:1:11:1 | PatternMatch | +| pattern_matching.swift:19:8:19:52 | ... .nested(...) | T | pattern_matching.swift:13:25:13:25 | T | +| pattern_matching.swift:19:44:19:49 | ... .some(...) | | {EXTERNAL LOCATION} | Optional | +| pattern_matching.swift:23:8:23:45 | ... .nested(...) | | pattern_matching.swift:7:1:11:1 | PatternMatch | +| pattern_matching.swift:23:8:23:45 | ... .nested(...) | T | pattern_matching.swift:13:25:13:25 | T | +| pattern_matching.swift:29:1:33:1 | Block | | pattern_matching.swift:7:1:11:1 | PatternMatch | +| pattern_matching.swift:29:1:33:1 | Block | T | {EXTERNAL LOCATION} | Bool | +| pattern_matching.swift:30:7:30:7 | x | | pattern_matching.swift:7:1:11:1 | PatternMatch | +| pattern_matching.swift:30:7:30:7 | x | T | {EXTERNAL LOCATION} | Int | +| pattern_matching.swift:30:11:30:32 | ... .value(...) | | pattern_matching.swift:7:1:11:1 | PatternMatch | +| pattern_matching.swift:30:11:30:32 | ... .value(...) | T | {EXTERNAL LOCATION} | Int | +| pattern_matching.swift:30:30:30:31 | 42 | | {EXTERNAL LOCATION} | Int | +| pattern_matching.swift:31:7:31:7 | y | | pattern_matching.swift:7:1:11:1 | PatternMatch | +| pattern_matching.swift:31:7:31:7 | y | T | {EXTERNAL LOCATION} | String | +| pattern_matching.swift:31:11:31:38 | ... .novalue | | pattern_matching.swift:7:1:11:1 | PatternMatch | +| pattern_matching.swift:31:11:31:38 | ... .novalue | T | {EXTERNAL LOCATION} | String | +| pattern_matching.swift:32:10:32:29 | ... .novalue | | pattern_matching.swift:7:1:11:1 | PatternMatch | +| pattern_matching.swift:32:10:32:29 | ... .novalue | T | {EXTERNAL LOCATION} | Bool | +| protocols.swift:8:7:8:12 | radius | | {EXTERNAL LOCATION} | Double | +| protocols.swift:10:3:12:3 | Block | | {EXTERNAL LOCATION} | Double | +| protocols.swift:10:8:10:13 | radius | | {EXTERNAL LOCATION} | Double | +| protocols.swift:11:5:11:8 | self | | protocols.swift:7:1:17:1 | Circle | +| protocols.swift:11:5:11:15 | ... .radius | | {EXTERNAL LOCATION} | Double | +| protocols.swift:11:5:11:24 | ... = ... | | {EXTERNAL LOCATION} | Double | +| protocols.swift:11:19:11:24 | radius | | {EXTERNAL LOCATION} | Double | +| protocols.swift:15:22:15:27 | radius | | {EXTERNAL LOCATION} | Double | +| protocols.swift:15:31:15:36 | radius | | {EXTERNAL LOCATION} | Double | +| protocols.swift:20:7:20:11 | width | | {EXTERNAL LOCATION} | Double | +| protocols.swift:21:7:21:12 | height | | {EXTERNAL LOCATION} | Double | +| protocols.swift:23:3:26:3 | Block | | {EXTERNAL LOCATION} | Double | +| protocols.swift:23:8:23:12 | width | | {EXTERNAL LOCATION} | Double | +| protocols.swift:23:23:23:28 | height | | {EXTERNAL LOCATION} | Double | +| protocols.swift:24:5:24:8 | self | | protocols.swift:19:1:31:1 | Rectangle | +| protocols.swift:24:5:24:14 | ... .width | | {EXTERNAL LOCATION} | Double | +| protocols.swift:24:5:24:22 | ... = ... | | {EXTERNAL LOCATION} | Double | +| protocols.swift:24:18:24:22 | width | | {EXTERNAL LOCATION} | Double | +| protocols.swift:25:5:25:8 | self | | protocols.swift:19:1:31:1 | Rectangle | +| protocols.swift:25:5:25:15 | ... .height | | {EXTERNAL LOCATION} | Double | +| protocols.swift:25:5:25:24 | ... = ... | | {EXTERNAL LOCATION} | Double | +| protocols.swift:25:19:25:24 | height | | {EXTERNAL LOCATION} | Double | +| protocols.swift:28:3:30:3 | Block | | {EXTERNAL LOCATION} | Double | +| protocols.swift:29:12:29:16 | width | | {EXTERNAL LOCATION} | Double | +| protocols.swift:29:12:29:25 | ... * ... | | {EXTERNAL LOCATION} | Double | +| protocols.swift:29:20:29:25 | height | | {EXTERNAL LOCATION} | Double | +| protocols.swift:34:7:34:7 | c | | protocols.swift:7:1:17:1 | Circle | +| protocols.swift:34:11:34:29 | Circle(...) | | protocols.swift:7:1:17:1 | Circle | +| protocols.swift:35:7:35:8 | a1 | | {EXTERNAL LOCATION} | Double | +| protocols.swift:35:12:35:12 | c | | protocols.swift:7:1:17:1 | Circle | +| protocols.swift:35:12:35:19 | ... .area(...) | | {EXTERNAL LOCATION} | Double | +| protocols.swift:37:7:37:7 | r | | protocols.swift:19:1:31:1 | Rectangle | +| protocols.swift:37:11:37:44 | Rectangle(...) | | protocols.swift:19:1:31:1 | Rectangle | +| protocols.swift:38:7:38:8 | a2 | | {EXTERNAL LOCATION} | Double | +| protocols.swift:38:12:38:12 | r | | protocols.swift:19:1:31:1 | Rectangle | +| protocols.swift:38:12:38:19 | ... .area(...) | | {EXTERNAL LOCATION} | Double | +| protocols.swift:51:7:51:11 | items | | {EXTERNAL LOCATION} | Array | +| protocols.swift:51:7:51:11 | items | Element | {EXTERNAL LOCATION} | Int | +| protocols.swift:53:3:55:3 | Block | | {EXTERNAL LOCATION} | Array | +| protocols.swift:53:3:55:3 | Block | Element | {EXTERNAL LOCATION} | Int | +| protocols.swift:53:8:53:12 | items | | {EXTERNAL LOCATION} | Array | +| protocols.swift:53:8:53:12 | items | Element | {EXTERNAL LOCATION} | Int | +| protocols.swift:54:5:54:8 | self | | protocols.swift:49:1:64:1 | IntContainer | +| protocols.swift:54:5:54:14 | ... .items | | {EXTERNAL LOCATION} | Array | +| protocols.swift:54:5:54:14 | ... .items | Element | {EXTERNAL LOCATION} | Int | +| protocols.swift:54:5:54:22 | ... = ... | | {EXTERNAL LOCATION} | Array | +| protocols.swift:54:5:54:22 | ... = ... | Element | {EXTERNAL LOCATION} | Int | +| protocols.swift:54:18:54:22 | items | | {EXTERNAL LOCATION} | Array | +| protocols.swift:54:18:54:22 | items | Element | {EXTERNAL LOCATION} | Int | +| protocols.swift:58:12:58:16 | items | | {EXTERNAL LOCATION} | Array | +| protocols.swift:58:12:58:16 | items | Element | {EXTERNAL LOCATION} | Int | +| protocols.swift:58:18:58:18 | 0 | | {EXTERNAL LOCATION} | Int | +| protocols.swift:62:12:62:16 | items | | {EXTERNAL LOCATION} | Array | +| protocols.swift:62:12:62:16 | items | Element | {EXTERNAL LOCATION} | Int | +| protocols.swift:67:7:67:8 | ic | | protocols.swift:49:1:64:1 | IntContainer | +| protocols.swift:67:12:67:41 | IntContainer(...) | | protocols.swift:49:1:64:1 | IntContainer | +| protocols.swift:67:32:67:40 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | +| protocols.swift:67:32:67:40 | ArrayLiteral | Element | {EXTERNAL LOCATION} | Int | +| protocols.swift:67:33:67:33 | 1 | | {EXTERNAL LOCATION} | Int | +| protocols.swift:67:36:67:36 | 2 | | {EXTERNAL LOCATION} | Int | +| protocols.swift:67:39:67:39 | 3 | | {EXTERNAL LOCATION} | Int | +| protocols.swift:68:7:68:10 | item | | {EXTERNAL LOCATION} | Int | +| protocols.swift:68:14:68:15 | ic | | protocols.swift:49:1:64:1 | IntContainer | +| protocols.swift:68:14:68:25 | ... .getItem(...) | | {EXTERNAL LOCATION} | Int | +| protocols.swift:69:7:69:9 | cnt | | {EXTERNAL LOCATION} | Int | +| protocols.swift:69:13:69:14 | ic | | protocols.swift:49:1:64:1 | IntContainer | +| protocols.swift:69:13:69:22 | ... .count(...) | | {EXTERNAL LOCATION} | Int | +| protocols.swift:83:7:83:10 | name | | {EXTERNAL LOCATION} | String | +| protocols.swift:84:7:84:14 | entityId | | {EXTERNAL LOCATION} | Int | +| protocols.swift:86:3:89:3 | Block | | {EXTERNAL LOCATION} | Int | +| protocols.swift:86:8:86:11 | name | | {EXTERNAL LOCATION} | String | +| protocols.swift:86:22:86:29 | entityId | | {EXTERNAL LOCATION} | Int | +| protocols.swift:87:5:87:8 | self | | protocols.swift:82:1:98:1 | Entity | +| protocols.swift:87:5:87:13 | ... .name | | {EXTERNAL LOCATION} | String | +| protocols.swift:87:5:87:20 | ... = ... | | {EXTERNAL LOCATION} | String | +| protocols.swift:87:17:87:20 | name | | {EXTERNAL LOCATION} | String | +| protocols.swift:88:5:88:8 | self | | protocols.swift:82:1:98:1 | Entity | +| protocols.swift:88:5:88:17 | ... .entityId | | {EXTERNAL LOCATION} | Int | +| protocols.swift:88:5:88:28 | ... = ... | | {EXTERNAL LOCATION} | Int | +| protocols.swift:88:21:88:28 | entityId | | {EXTERNAL LOCATION} | Int | +| protocols.swift:91:3:93:3 | Block | | {EXTERNAL LOCATION} | String | +| protocols.swift:92:12:92:15 | name | | {EXTERNAL LOCATION} | String | +| protocols.swift:95:3:97:3 | Block | | {EXTERNAL LOCATION} | Int | +| protocols.swift:96:12:96:19 | entityId | | {EXTERNAL LOCATION} | Int | +| protocols.swift:101:7:101:7 | e | | protocols.swift:82:1:98:1 | Entity | +| protocols.swift:101:11:101:44 | Entity(...) | | protocols.swift:82:1:98:1 | Entity | +| protocols.swift:101:24:101:29 | "test" | | {EXTERNAL LOCATION} | String | +| protocols.swift:101:42:101:43 | 42 | | {EXTERNAL LOCATION} | Int | +| protocols.swift:102:7:102:7 | d | | {EXTERNAL LOCATION} | String | +| protocols.swift:102:11:102:11 | e | | protocols.swift:82:1:98:1 | Entity | +| protocols.swift:102:11:102:21 | ... .display(...) | | {EXTERNAL LOCATION} | String | +| protocols.swift:103:7:103:9 | eid | | {EXTERNAL LOCATION} | Int | +| protocols.swift:103:13:103:13 | e | | protocols.swift:82:1:98:1 | Entity | +| protocols.swift:103:13:103:18 | ... .id(...) | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:3:1:5:1 | Block | | type_constraints.swift:3:12:3:24 | T | +| type_constraints.swift:3:29:3:29 | a | | type_constraints.swift:3:12:3:24 | T | +| type_constraints.swift:3:37:3:37 | b | | type_constraints.swift:3:12:3:24 | T | +| type_constraints.swift:4:6:4:6 | a | | type_constraints.swift:3:12:3:24 | T | +| type_constraints.swift:4:6:4:10 | ... < ... | | type_constraints.swift:3:12:3:24 | T | +| type_constraints.swift:4:10:4:10 | b | | type_constraints.swift:3:12:3:24 | T | +| type_constraints.swift:4:21:4:21 | a | | type_constraints.swift:3:12:3:24 | T | +| type_constraints.swift:4:39:4:39 | b | | type_constraints.swift:3:12:3:24 | T | +| type_constraints.swift:7:1:9:1 | Block | | type_constraints.swift:7:12:7:12 | T | +| type_constraints.swift:7:17:7:17 | a | | type_constraints.swift:7:12:7:12 | T | +| type_constraints.swift:7:25:7:25 | b | | type_constraints.swift:7:12:7:12 | T | +| type_constraints.swift:8:6:8:6 | a | | type_constraints.swift:7:12:7:12 | T | +| type_constraints.swift:8:6:8:10 | ... > ... | | type_constraints.swift:7:12:7:12 | T | +| type_constraints.swift:8:10:8:10 | b | | type_constraints.swift:7:12:7:12 | T | +| type_constraints.swift:8:21:8:21 | a | | type_constraints.swift:7:12:7:12 | T | +| type_constraints.swift:8:39:8:39 | b | | type_constraints.swift:7:12:7:12 | T | +| type_constraints.swift:12:7:12:8 | m1 | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:12:12:12:22 | minOf(...) | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:12:18:12:18 | 3 | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:12:21:12:21 | 7 | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:13:7:13:8 | m2 | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:13:12:13:26 | minOf(...) | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:13:18:13:20 | "a" | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:13:23:13:25 | "z" | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:14:7:14:8 | m3 | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:14:12:14:22 | maxOf(...) | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:14:18:14:18 | 3 | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:14:21:14:21 | 7 | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:15:7:15:8 | m4 | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:15:12:15:26 | maxOf(...) | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:15:18:15:20 | "a" | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:15:23:15:25 | "z" | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:29:7:29:9 | tag | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:30:7:30:14 | priority | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:32:3:35:3 | Block | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:32:8:32:10 | tag | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:32:21:32:28 | priority | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:33:5:33:8 | self | | type_constraints.swift:28:1:44:1 | TaggedItem | +| type_constraints.swift:33:5:33:12 | ... .tag | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:33:5:33:18 | ... = ... | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:33:16:33:18 | tag | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:34:5:34:8 | self | | type_constraints.swift:28:1:44:1 | TaggedItem | +| type_constraints.swift:34:5:34:17 | ... .priority | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:34:5:34:28 | ... = ... | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:34:21:34:28 | priority | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:37:3:39:3 | Block | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:38:12:38:14 | tag | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:41:3:43:3 | Block | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:42:12:42:19 | priority | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:46:48:46:51 | item | | type_constraints.swift:46:18:46:43 | T | +| type_constraints.swift:47:10:47:13 | item | | type_constraints.swift:46:18:46:43 | T | +| type_constraints.swift:50:1:53:1 | Block | | type_constraints.swift:50:25:50:25 | T | +| type_constraints.swift:50:30:50:30 | a | | type_constraints.swift:50:25:50:25 | T | +| type_constraints.swift:50:38:50:38 | b | | type_constraints.swift:50:25:50:25 | T | +| type_constraints.swift:52:10:52:10 | a | | type_constraints.swift:50:25:50:25 | T | +| type_constraints.swift:52:10:52:15 | ... == ... | | type_constraints.swift:50:25:50:25 | T | +| type_constraints.swift:52:15:52:15 | b | | type_constraints.swift:50:25:50:25 | T | +| type_constraints.swift:56:7:56:10 | item | | type_constraints.swift:28:1:44:1 | TaggedItem | +| type_constraints.swift:56:14:56:46 | TaggedItem(...) | | type_constraints.swift:28:1:44:1 | TaggedItem | +| type_constraints.swift:56:30:56:32 | "x" | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:56:45:56:45 | 1 | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:57:7:57:7 | s | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:57:11:57:27 | showAndSort(...) | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:57:23:57:26 | item | | type_constraints.swift:28:1:44:1 | TaggedItem | +| type_constraints.swift:58:7:58:8 | eq | | {EXTERNAL LOCATION} | Bool | +| type_constraints.swift:58:12:58:41 | showSortAndCompare(...) | | {EXTERNAL LOCATION} | Bool | +| type_constraints.swift:58:31:58:34 | item | | type_constraints.swift:28:1:44:1 | TaggedItem | +| type_constraints.swift:58:37:58:40 | item | | type_constraints.swift:28:1:44:1 | TaggedItem | +| type_constraints.swift:64:7:64:11 | first | | type_constraints.swift:63:18:63:31 | T | +| type_constraints.swift:65:7:65:12 | second | | type_constraints.swift:63:33:63:45 | U | +| type_constraints.swift:67:3:70:3 | Block | | type_constraints.swift:63:33:63:45 | U | +| type_constraints.swift:67:8:67:12 | first | | type_constraints.swift:63:18:63:31 | T | +| type_constraints.swift:67:18:67:23 | second | | type_constraints.swift:63:33:63:45 | U | +| type_constraints.swift:68:5:68:8 | self | | type_constraints.swift:63:1:79:1 | SortedPair | +| type_constraints.swift:68:5:68:8 | self | T | type_constraints.swift:63:18:63:31 | T | +| type_constraints.swift:68:5:68:8 | self | U | type_constraints.swift:63:33:63:45 | U | +| type_constraints.swift:68:5:68:14 | ... .first | | type_constraints.swift:63:18:63:31 | T | +| type_constraints.swift:68:5:68:22 | ... = ... | | type_constraints.swift:63:18:63:31 | T | +| type_constraints.swift:68:18:68:22 | first | | type_constraints.swift:63:18:63:31 | T | +| type_constraints.swift:69:5:69:8 | self | | type_constraints.swift:63:1:79:1 | SortedPair | +| type_constraints.swift:69:5:69:8 | self | T | type_constraints.swift:63:18:63:31 | T | +| type_constraints.swift:69:5:69:8 | self | U | type_constraints.swift:63:33:63:45 | U | +| type_constraints.swift:69:5:69:15 | ... .second | | type_constraints.swift:63:33:63:45 | U | +| type_constraints.swift:69:5:69:24 | ... = ... | | type_constraints.swift:63:33:63:45 | U | +| type_constraints.swift:69:19:69:24 | second | | type_constraints.swift:63:33:63:45 | U | +| type_constraints.swift:72:3:74:3 | Block | | type_constraints.swift:63:18:63:31 | T | +| type_constraints.swift:72:28:72:32 | other | | type_constraints.swift:63:18:63:31 | T | +| type_constraints.swift:73:12:73:16 | first | | type_constraints.swift:63:18:63:31 | T | +| type_constraints.swift:73:12:73:24 | ... < ... | | type_constraints.swift:63:18:63:31 | T | +| type_constraints.swift:73:20:73:24 | other | | type_constraints.swift:63:18:63:31 | T | +| type_constraints.swift:76:3:78:3 | Block | | type_constraints.swift:63:33:63:45 | U | +| type_constraints.swift:76:29:76:33 | other | | type_constraints.swift:63:33:63:45 | U | +| type_constraints.swift:77:12:77:17 | second | | type_constraints.swift:63:33:63:45 | U | +| type_constraints.swift:77:12:77:25 | ... < ... | | type_constraints.swift:63:33:63:45 | U | +| type_constraints.swift:77:21:77:25 | other | | type_constraints.swift:63:33:63:45 | U | +| type_constraints.swift:82:7:82:8 | sp | | type_constraints.swift:63:1:79:1 | SortedPair | +| type_constraints.swift:82:7:82:8 | sp | T | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:82:7:82:8 | sp | U | {EXTERNAL LOCATION} | String | +| type_constraints.swift:82:12:82:44 | SortedPair(...) | | type_constraints.swift:63:1:79:1 | SortedPair | +| type_constraints.swift:82:12:82:44 | SortedPair(...) | T | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:82:12:82:44 | SortedPair(...) | U | {EXTERNAL LOCATION} | String | +| type_constraints.swift:82:30:82:30 | 3 | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:82:41:82:43 | "b" | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:83:7:83:8 | r1 | | {EXTERNAL LOCATION} | Bool | +| type_constraints.swift:83:12:83:13 | sp | | type_constraints.swift:63:1:79:1 | SortedPair | +| type_constraints.swift:83:12:83:13 | sp | T | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:83:12:83:13 | sp | U | {EXTERNAL LOCATION} | String | +| type_constraints.swift:83:12:83:37 | ... .isFirstSmaller(...) | | {EXTERNAL LOCATION} | Bool | +| type_constraints.swift:83:36:83:36 | 5 | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:84:7:84:8 | r2 | | {EXTERNAL LOCATION} | Bool | +| type_constraints.swift:84:12:84:13 | sp | | type_constraints.swift:63:1:79:1 | SortedPair | +| type_constraints.swift:84:12:84:13 | sp | T | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:84:12:84:13 | sp | U | {EXTERNAL LOCATION} | String | +| type_constraints.swift:84:12:84:40 | ... .isSecondSmaller(...) | | {EXTERNAL LOCATION} | Bool | +| type_constraints.swift:84:37:84:39 | "z" | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:96:7:96:11 | items | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:96:7:96:11 | items | Element | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:98:3:100:3 | Block | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:98:3:100:3 | Block | Element | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:98:8:98:12 | items | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:98:8:98:12 | items | Element | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:99:5:99:8 | self | | type_constraints.swift:94:1:105:1 | IntArray | +| type_constraints.swift:99:5:99:14 | ... .items | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:99:5:99:14 | ... .items | Element | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:99:5:99:22 | ... = ... | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:99:5:99:22 | ... = ... | Element | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:99:18:99:22 | items | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:99:18:99:22 | items | Element | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:103:12:103:16 | items | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:103:12:103:16 | items | Element | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:103:18:103:18 | 0 | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:109:7:109:11 | items | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:109:7:109:11 | items | Element | {EXTERNAL LOCATION} | String | +| type_constraints.swift:111:3:113:3 | Block | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:111:3:113:3 | Block | Element | {EXTERNAL LOCATION} | String | +| type_constraints.swift:111:8:111:12 | items | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:111:8:111:12 | items | Element | {EXTERNAL LOCATION} | String | +| type_constraints.swift:112:5:112:8 | self | | type_constraints.swift:107:1:118:1 | StringArray | +| type_constraints.swift:112:5:112:14 | ... .items | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:112:5:112:14 | ... .items | Element | {EXTERNAL LOCATION} | String | +| type_constraints.swift:112:5:112:22 | ... = ... | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:112:5:112:22 | ... = ... | Element | {EXTERNAL LOCATION} | String | +| type_constraints.swift:112:18:112:22 | items | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:112:18:112:22 | items | Element | {EXTERNAL LOCATION} | String | +| type_constraints.swift:116:12:116:16 | items | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:116:12:116:16 | items | Element | {EXTERNAL LOCATION} | String | +| type_constraints.swift:116:18:116:18 | 0 | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:120:45:120:53 | container | | type_constraints.swift:120:19:120:37 | C | +| type_constraints.swift:121:10:121:18 | container | | type_constraints.swift:120:19:120:37 | C | +| type_constraints.swift:124:45:124:53 | container | | type_constraints.swift:124:19:124:37 | C | +| type_constraints.swift:125:10:125:18 | container | | type_constraints.swift:124:19:124:37 | C | +| type_constraints.swift:129:7:129:8 | ia | | type_constraints.swift:94:1:105:1 | IntArray | +| type_constraints.swift:129:12:129:36 | IntArray(...) | | type_constraints.swift:94:1:105:1 | IntArray | +| type_constraints.swift:129:28:129:35 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:129:28:129:35 | ArrayLiteral | Element | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:129:29:129:30 | 10 | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:129:33:129:34 | 20 | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:130:7:130:8 | sa | | type_constraints.swift:107:1:118:1 | StringArray | +| type_constraints.swift:130:12:130:46 | StringArray(...) | | type_constraints.swift:107:1:118:1 | StringArray | +| type_constraints.swift:130:31:130:45 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:130:31:130:45 | ArrayLiteral | Element | {EXTERNAL LOCATION} | String | +| type_constraints.swift:130:32:130:35 | "hi" | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:130:38:130:44 | "there" | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:131:31:131:32 | ia | | type_constraints.swift:94:1:105:1 | IntArray | +| type_constraints.swift:132:31:132:32 | sa | | type_constraints.swift:107:1:118:1 | StringArray | +| type_constraints.swift:138:7:138:11 | speed | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:140:3:142:3 | Block | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:140:8:140:12 | speed | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:141:5:141:8 | self | | type_constraints.swift:137:1:147:1 | Vehicle | +| type_constraints.swift:141:5:141:14 | ... .speed | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:141:5:141:22 | ... = ... | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:141:18:141:22 | speed | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:144:3:146:3 | Block | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:145:12:145:20 | "vehicle" | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:150:3:152:3 | Block | | type_constraints.swift:137:1:147:1 | Vehicle | +| type_constraints.swift:150:17:150:21 | speed | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:151:5:151:9 | super | | type_constraints.swift:137:1:147:1 | Vehicle | +| type_constraints.swift:151:5:151:28 | ... .init(...) | | type_constraints.swift:137:1:147:1 | Vehicle | +| type_constraints.swift:151:23:151:27 | speed | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:154:3:156:3 | Block | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:155:12:155:16 | "car" | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:158:3:160:3 | Block | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:159:12:159:17 | "beep" | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:164:3:166:3 | Block | | type_constraints.swift:137:1:147:1 | Vehicle | +| type_constraints.swift:164:17:164:21 | speed | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:165:5:165:9 | super | | type_constraints.swift:137:1:147:1 | Vehicle | +| type_constraints.swift:165:5:165:28 | ... .init(...) | | type_constraints.swift:137:1:147:1 | Vehicle | +| type_constraints.swift:165:23:165:27 | speed | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:168:3:170:3 | Block | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:169:12:169:18 | "truck" | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:172:3:174:3 | Block | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:173:12:173:20 | "hauling" | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:177:36:177:36 | v | | type_constraints.swift:177:22:177:31 | T | +| type_constraints.swift:178:10:178:10 | v | | type_constraints.swift:177:22:177:31 | T | +| type_constraints.swift:182:7:182:9 | car | | type_constraints.swift:149:1:161:1 | Car | +| type_constraints.swift:182:13:182:27 | Car(...) | | type_constraints.swift:149:1:161:1 | Car | +| type_constraints.swift:182:24:182:26 | 100 | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:183:7:183:11 | truck | | type_constraints.swift:163:1:175:1 | Truck | +| type_constraints.swift:183:15:183:30 | Truck(...) | | type_constraints.swift:163:1:175:1 | Truck | +| type_constraints.swift:183:28:183:29 | 60 | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:184:7:184:8 | d1 | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:184:12:184:31 | describeVehicle(...) | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:184:28:184:30 | car | | type_constraints.swift:149:1:161:1 | Car | +| type_constraints.swift:185:7:185:8 | d2 | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:185:12:185:33 | describeVehicle(...) | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:185:28:185:32 | truck | | type_constraints.swift:163:1:175:1 | Truck | +| type_constraints.swift:186:7:186:7 | h | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:186:11:186:13 | car | | type_constraints.swift:149:1:161:1 | Car | +| type_constraints.swift:186:11:186:20 | ... .honk(...) | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:187:7:187:8 | hl | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:187:12:187:16 | truck | | type_constraints.swift:163:1:175:1 | Truck | +| type_constraints.swift:187:12:187:23 | ... .haul(...) | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:193:18:193:20 | lhs | | type_constraints.swift:192:1:194:1 | Summable | +| type_constraints.swift:193:29:193:31 | rhs | | type_constraints.swift:192:1:194:1 | Summable | +| type_constraints.swift:201:7:201:12 | values | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:201:7:201:12 | values | Element | type_constraints.swift:200:20:200:20 | T | +| type_constraints.swift:203:3:205:3 | Block | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:203:3:205:3 | Block | Element | type_constraints.swift:200:20:200:20 | T | +| type_constraints.swift:203:8:203:13 | values | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:203:8:203:13 | values | Element | type_constraints.swift:200:20:200:20 | T | +| type_constraints.swift:204:5:204:8 | self | | type_constraints.swift:200:1:210:1 | Accumulator | +| type_constraints.swift:204:5:204:8 | self | T | type_constraints.swift:200:20:200:20 | T | +| type_constraints.swift:204:5:204:15 | ... .values | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:204:5:204:15 | ... .values | Element | type_constraints.swift:200:20:200:20 | T | +| type_constraints.swift:204:5:204:24 | ... = ... | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:204:5:204:24 | ... = ... | Element | type_constraints.swift:200:20:200:20 | T | +| type_constraints.swift:204:19:204:24 | values | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:204:19:204:24 | values | Element | type_constraints.swift:200:20:200:20 | T | +| type_constraints.swift:208:12:208:17 | values | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:208:12:208:17 | values | Element | type_constraints.swift:200:20:200:20 | T | +| type_constraints.swift:214:12:214:17 | values | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:214:19:214:19 | 0 | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:214:24:214:29 | values | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:214:31:214:31 | 1 | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:220:12:220:17 | values | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:220:35:220:48 | FunctionExpr | | {EXTERNAL LOCATION} | Function | +| type_constraints.swift:225:7:225:12 | intAcc | | type_constraints.swift:200:1:210:1 | Accumulator | +| type_constraints.swift:225:7:225:12 | intAcc | T | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:225:16:225:45 | Accumulator(...) | | type_constraints.swift:200:1:210:1 | Accumulator | +| type_constraints.swift:225:16:225:45 | Accumulator(...) | T | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:225:36:225:44 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:225:36:225:44 | ArrayLiteral | Element | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:225:37:225:37 | 1 | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:225:40:225:40 | 2 | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:225:43:225:43 | 3 | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:226:7:226:9 | cnt | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:226:13:226:18 | intAcc | | type_constraints.swift:200:1:210:1 | Accumulator | +| type_constraints.swift:226:13:226:18 | intAcc | T | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:226:13:226:26 | ... .count(...) | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:227:13:227:18 | intAcc | | type_constraints.swift:200:1:210:1 | Accumulator | +| type_constraints.swift:227:13:227:18 | intAcc | T | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:228:7:228:9 | has | | {EXTERNAL LOCATION} | Bool | +| type_constraints.swift:228:13:228:18 | intAcc | | type_constraints.swift:200:1:210:1 | Accumulator | +| type_constraints.swift:228:13:228:18 | intAcc | T | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:228:13:228:30 | ... .contains(...) | | {EXTERNAL LOCATION} | Bool | +| type_constraints.swift:228:29:228:29 | 2 | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:236:33:236:37 | items | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:236:33:236:37 | items | Element | type_constraints.swift:236:18:236:28 | T | +| type_constraints.swift:237:12:237:16 | items | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:237:12:237:16 | items | Element | type_constraints.swift:236:18:236:28 | T | +| type_constraints.swift:237:18:237:18 | 0 | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:237:23:237:27 | items | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:237:23:237:27 | items | Element | type_constraints.swift:236:18:236:28 | T | +| type_constraints.swift:237:29:237:29 | 1 | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:240:3:242:3 | Block | | {EXTERNAL LOCATION} | Bool | +| type_constraints.swift:240:44:240:44 | a | | type_constraints.swift:240:14:240:26 | A | +| type_constraints.swift:240:52:240:52 | b | | type_constraints.swift:240:28:240:39 | B | +| type_constraints.swift:241:12:241:15 | true | | {EXTERNAL LOCATION} | Bool | +| type_constraints.swift:246:7:246:7 | t | | type_constraints.swift:233:1:243:1 | Transformer | +| type_constraints.swift:246:11:246:23 | Transformer(...) | | type_constraints.swift:233:1:243:1 | Transformer | +| type_constraints.swift:247:7:247:8 | r1 | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:247:12:247:12 | t | | type_constraints.swift:233:1:243:1 | Transformer | +| type_constraints.swift:247:12:247:33 | ... .transform(...) | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:247:24:247:32 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:247:24:247:32 | ArrayLiteral | Element | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:247:25:247:25 | 3 | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:247:28:247:28 | 1 | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:247:31:247:31 | 2 | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:248:7:248:8 | r2 | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:248:12:248:12 | t | | type_constraints.swift:233:1:243:1 | Transformer | +| type_constraints.swift:248:12:248:39 | ... .transform(...) | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:248:24:248:38 | ArrayLiteral | | {EXTERNAL LOCATION} | Array | +| type_constraints.swift:248:24:248:38 | ArrayLiteral | Element | {EXTERNAL LOCATION} | String | +| type_constraints.swift:248:25:248:27 | "c" | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:248:30:248:32 | "a" | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:248:35:248:37 | "b" | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:249:7:249:8 | r3 | | {EXTERNAL LOCATION} | Bool | +| type_constraints.swift:249:12:249:12 | t | | type_constraints.swift:233:1:243:1 | Transformer | +| type_constraints.swift:249:12:249:26 | ... .merge(...) | | {EXTERNAL LOCATION} | Bool | +| type_constraints.swift:249:20:249:20 | 1 | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:249:23:249:25 | "x" | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:254:1:258:1 | Block | | type_constraints.swift:254:12:254:24 | T | +| type_constraints.swift:254:29:254:33 | value | | type_constraints.swift:254:12:254:24 | T | +| type_constraints.swift:254:43:254:47 | lower | | type_constraints.swift:254:12:254:24 | T | +| type_constraints.swift:254:57:254:61 | upper | | type_constraints.swift:254:12:254:24 | T | +| type_constraints.swift:255:6:255:10 | value | | type_constraints.swift:254:12:254:24 | T | +| type_constraints.swift:255:6:255:18 | ... < ... | | type_constraints.swift:254:12:254:24 | T | +| type_constraints.swift:255:14:255:18 | lower | | type_constraints.swift:254:12:254:24 | T | +| type_constraints.swift:255:29:255:33 | lower | | type_constraints.swift:254:12:254:24 | T | +| type_constraints.swift:256:6:256:10 | value | | type_constraints.swift:254:12:254:24 | T | +| type_constraints.swift:256:6:256:18 | ... > ... | | type_constraints.swift:254:12:254:24 | T | +| type_constraints.swift:256:14:256:18 | upper | | type_constraints.swift:254:12:254:24 | T | +| type_constraints.swift:256:29:256:33 | upper | | type_constraints.swift:254:12:254:24 | T | +| type_constraints.swift:257:10:257:14 | value | | type_constraints.swift:254:12:254:24 | T | +| type_constraints.swift:261:7:261:8 | r1 | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:261:12:261:36 | clamp(...) | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:261:18:261:18 | 5 | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:261:26:261:26 | 0 | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:261:34:261:35 | 10 | | {EXTERNAL LOCATION} | Int | +| type_constraints.swift:263:7:263:8 | r3 | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:263:12:263:41 | clamp(...) | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:263:18:263:20 | "m" | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:263:28:263:30 | "a" | | {EXTERNAL LOCATION} | String | +| type_constraints.swift:263:38:263:40 | "z" | | {EXTERNAL LOCATION} | String | +testFailures +| pattern_matching.swift:3:15:3:34 | // $ type=number:Int | Missing result: type=number:Int | +| pattern_matching.swift:4:13:4:33 | // $ type=text:String | Missing result: type=text:String | +| pattern_matching.swift:18:16:18:32 | // $ type=value:T | Missing result: type=value:T | +| pattern_matching.swift:19:44:19:49 | ... .some(...) | Unexpected result: target=Optional.some | +| pattern_matching.swift:20:16:20:32 | // $ type=value:T | Missing result: type=value:T | +| pattern_matching.swift:21:16:21:34 | // $ type=count:Int | Missing result: type=count:Int | +| pattern_matching.swift:22:16:22:37 | // $ type=label:String | Missing result: type=label:String | +| pattern_matching.swift:24:16:24:32 | // $ type=value:T | Missing result: type=value:T | +| pattern_matching.swift:25:16:25:34 | // $ type=count:Int | Missing result: type=count:Int | +| protocols.swift:11:5:11:15 | ... .radius | Unexpected result: field=Circle.radius | +| protocols.swift:15:22:15:27 | radius | Unexpected result: field=Circle.radius | +| protocols.swift:15:31:15:36 | radius | Unexpected result: field=Circle.radius | +| protocols.swift:15:39:15:62 | // $ type=.radius:Double | Missing result: type=.radius:Double | +| protocols.swift:24:5:24:14 | ... .width | Unexpected result: field=Rectangle.width | +| protocols.swift:25:5:25:15 | ... .height | Unexpected result: field=Rectangle.height | +| protocols.swift:29:12:29:16 | width | Unexpected result: field=Rectangle.width | +| protocols.swift:29:20:29:25 | height | Unexpected result: field=Rectangle.height | +| protocols.swift:29:28:29:50 | // $ type=.width:Double | Missing result: type=.width:Double | +| protocols.swift:54:5:54:14 | ... .items | Unexpected result: field=IntContainer.items | +| protocols.swift:58:12:58:16 | items | Unexpected result: field=IntContainer.items | +| protocols.swift:62:12:62:16 | items | Unexpected result: field=IntContainer.items | +| protocols.swift:87:5:87:13 | ... .name | Unexpected result: field=Entity.name | +| protocols.swift:88:5:88:17 | ... .entityId | Unexpected result: field=Entity.entityId | +| protocols.swift:92:12:92:15 | name | Unexpected result: field=Entity.name | +| protocols.swift:92:18:92:39 | // $ type=.name:String | Missing result: type=.name:String | +| protocols.swift:96:12:96:19 | entityId | Unexpected result: field=Entity.entityId | +| protocols.swift:96:22:96:44 | // $ type=.entityId:Int | Missing result: type=.entityId:Int | +| type_constraints.swift:12:12:12:22 | minOf(...) | Unexpected result: target=minOf | +| type_constraints.swift:12:25:12:59 | // $ type=m1:Int target=minOf(_:_:) | Missing result: target=minOf(_:_:) | +| type_constraints.swift:13:12:13:26 | minOf(...) | Unexpected result: target=minOf | +| type_constraints.swift:13:29:13:66 | // $ type=m2:String target=minOf(_:_:) | Missing result: target=minOf(_:_:) | +| type_constraints.swift:14:12:14:22 | maxOf(...) | Unexpected result: target=maxOf | +| type_constraints.swift:14:25:14:59 | // $ type=m3:Int target=maxOf(_:_:) | Missing result: target=maxOf(_:_:) | +| type_constraints.swift:15:12:15:26 | maxOf(...) | Unexpected result: target=maxOf | +| type_constraints.swift:15:29:15:66 | // $ type=m4:String target=maxOf(_:_:) | Missing result: target=maxOf(_:_:) | +| type_constraints.swift:33:5:33:12 | ... .tag | Unexpected result: field=TaggedItem.tag | +| type_constraints.swift:34:5:34:17 | ... .priority | Unexpected result: field=TaggedItem.priority | +| type_constraints.swift:38:12:38:14 | tag | Unexpected result: field=TaggedItem.tag | +| type_constraints.swift:38:17:38:37 | // $ type=.tag:String | Missing result: type=.tag:String | +| type_constraints.swift:42:12:42:19 | priority | Unexpected result: field=TaggedItem.priority | +| type_constraints.swift:42:22:42:44 | // $ type=.priority:Int | Missing result: type=.priority:Int | +| type_constraints.swift:47:26:47:57 | // $ target=Displayable2.display | Missing result: target=Displayable2.display | +| type_constraints.swift:57:11:57:27 | showAndSort(...) | Unexpected result: target=showAndSort | +| type_constraints.swift:57:30:57:70 | // $ type=s:String target=showAndSort(_:) | Missing result: target=showAndSort(_:) | +| type_constraints.swift:58:12:58:41 | showSortAndCompare(...) | Unexpected result: target=showSortAndCompare | +| type_constraints.swift:58:44:58:92 | // $ type=eq:Bool target=showSortAndCompare(_:_:) | Missing result: target=showSortAndCompare(_:_:) | +| type_constraints.swift:68:5:68:14 | ... .first | Unexpected result: field=SortedPair.first | +| type_constraints.swift:69:5:69:15 | ... .second | Unexpected result: field=SortedPair.second | +| type_constraints.swift:73:12:73:16 | first | Unexpected result: field=SortedPair.first | +| type_constraints.swift:77:12:77:17 | second | Unexpected result: field=SortedPair.second | +| type_constraints.swift:99:5:99:14 | ... .items | Unexpected result: field=IntArray.items | +| type_constraints.swift:103:12:103:16 | items | Unexpected result: field=IntArray.items | +| type_constraints.swift:112:5:112:14 | ... .items | Unexpected result: field=StringArray.items | +| type_constraints.swift:116:12:116:16 | items | Unexpected result: field=StringArray.items | +| type_constraints.swift:121:29:121:62 | // $ target=ElementContainer.first | Missing result: target=ElementContainer.first | +| type_constraints.swift:125:29:125:62 | // $ target=ElementContainer.first | Missing result: target=ElementContainer.first | +| type_constraints.swift:131:12:131:33 | extractFirst(...) | Unexpected result: target=extractFirst | +| type_constraints.swift:131:36:131:81 | // $ type=r1:Int target=extractFirst(from:Int) | Missing result: target=extractFirst(from:Int) | +| type_constraints.swift:131:36:131:81 | // $ type=r1:Int target=extractFirst(from:Int) | Missing result: type=r1:Int | +| type_constraints.swift:132:12:132:33 | extractFirst(...) | Unexpected result: target=extractFirst | +| type_constraints.swift:132:36:132:87 | // $ type=r2:String target=extractFirst(from:String) | Missing result: target=extractFirst(from:String) | +| type_constraints.swift:132:36:132:87 | // $ type=r2:String target=extractFirst(from:String) | Missing result: type=r2:String | +| type_constraints.swift:141:5:141:14 | ... .speed | Unexpected result: field=Vehicle.speed | +| type_constraints.swift:178:24:178:51 | // $ target=Vehicle.describe | Missing result: target=Vehicle.describe | +| type_constraints.swift:184:12:184:31 | describeVehicle(...) | Unexpected result: target=describeVehicle | +| type_constraints.swift:184:34:184:79 | // $ type=d1:String target=describeVehicle(_:) | Missing result: target=describeVehicle(_:) | +| type_constraints.swift:185:12:185:33 | describeVehicle(...) | Unexpected result: target=describeVehicle | +| type_constraints.swift:185:36:185:81 | // $ type=d2:String target=describeVehicle(_:) | Missing result: target=describeVehicle(_:) | +| type_constraints.swift:204:5:204:15 | ... .values | Unexpected result: field=Accumulator.values | +| type_constraints.swift:208:12:208:17 | values | Unexpected result: field=Accumulator.values | +| type_constraints.swift:214:12:214:17 | values | Unexpected result: field=Accumulator.values | +| type_constraints.swift:214:24:214:29 | values | Unexpected result: field=Accumulator.values | +| type_constraints.swift:214:35:214:56 | // $ target=Summable.+ | Missing result: target=Summable.+ | +| type_constraints.swift:220:12:220:17 | values | Unexpected result: field=Accumulator.values | +| type_constraints.swift:227:29:227:70 | // $ type=tot:Int target=Accumulator.total | Missing result: type=tot:Int | +| type_constraints.swift:237:33:237:54 | // $ target=Summable.+ | Missing result: target=Summable.+ | +| type_constraints.swift:261:12:261:36 | clamp(...) | Unexpected result: target=clamp | +| type_constraints.swift:261:39:261:79 | // $ type=r1:Int target=clamp(_:min:max:) | Missing result: target=clamp(_:min:max:) | +| type_constraints.swift:262:12:262:41 | clamp(...) | Unexpected result: target=clamp | +| type_constraints.swift:262:44:262:87 | // $ type=r2:Double target=clamp(_:min:max:) | Missing result: target=clamp(_:min:max:) | +| type_constraints.swift:262:44:262:87 | // $ type=r2:Double target=clamp(_:min:max:) | Missing result: type=r2:Double | +| type_constraints.swift:263:12:263:41 | clamp(...) | Unexpected result: target=clamp | +| type_constraints.swift:263:44:263:87 | // $ type=r3:String target=clamp(_:min:max:) | Missing result: target=clamp(_:min:max:) | diff --git a/unified/ql/test/library-tests/type-inference/type-inference.ql b/unified/ql/test/library-tests/type-inference/type-inference.ql new file mode 100644 index 000000000000..45870e5fc1ab --- /dev/null +++ b/unified/ql/test/library-tests/type-inference/type-inference.ql @@ -0,0 +1,48 @@ +import utils.test.InlineExpectationsTest +import utils.test.TestUtils +import codeql.unified.internal.typeinference.Type +import codeql.unified.internal.typeinference.TypeInference as TypeInference +import codeql.unified.internal.StaticNameBinding +import TypeInference + +private predicate relevantNode(AstNode n) { n.fromSource() } + +query predicate inferCertainType(AstNode n, TypePath path, Type t) { + t = TypeInference::inferTypeCertain(n, path) and + not t instanceof PseudoType and + relevantNode(n) +} + +query predicate inferType(AstNode n, TypePath path, Type t) { + t = TypeInference::inferType(n, path) and + not t instanceof PseudoType and + relevantNode(n) +} + +module ResolveTest implements TestSig { + string getARelevantTag() { + result = "target" + or + result = "field" + } + + predicate hasActualResult(Location location, string element, string tag, string value) { + exists(Callable c, CallExpr ce | + c = resolveCallTarget(ce, _) and + location = ce.getLocation() and + element = ce.toString() and + callableName(c, value) and + tag = "target" + ) + or + exists(VariableDeclaration field, Expr access | + field = resolveFieldAccess(access) and + location = access.getLocation() and + element = access.toString() and + nameBinding(field.getPattern(), value) and + tag = "field" + ) + } +} + +import MakeTest> diff --git a/unified/ql/test/library-tests/type-inference/type-inference.qlref b/unified/ql/test/library-tests/type-inference/type-inference.qlref new file mode 100644 index 000000000000..03d8a9288aab --- /dev/null +++ b/unified/ql/test/library-tests/type-inference/type-inference.qlref @@ -0,0 +1,2 @@ +query: type-inference.ql +postprocess: utils/test/ExternalLocationPostProcessing.ql \ No newline at end of file diff --git a/unified/ql/test/library-tests/type-inference/type_constraints.swift b/unified/ql/test/library-tests/type-inference/type_constraints.swift new file mode 100644 index 000000000000..25949482f0a2 --- /dev/null +++ b/unified/ql/test/library-tests/type-inference/type_constraints.swift @@ -0,0 +1,264 @@ +// --- where clause on generic function --- + +func minOf(_ a: T, _ b: T) -> T { + if a < b { return a } else { return b } +} + +func maxOf(_ a: T, _ b: T) -> T where T: Comparable { + if a > b { return a } else { return b } +} + +func testWhereClause() { + let m1 = minOf(3, 7) // $ type=m1:Int target=minOf(_:_:) + let m2 = minOf("a", "z") // $ type=m2:String target=minOf(_:_:) + let m3 = maxOf(3, 7) // $ type=m3:Int target=maxOf(_:_:) + let m4 = maxOf("a", "z") // $ type=m4:String target=maxOf(_:_:) +} + +// --- Multiple constraints on a single type parameter --- + +protocol Displayable2 { + func display() -> String +} + +protocol Sortable { + func sortKey() -> Int +} + +struct TaggedItem: Displayable2, Sortable, Equatable { + var tag: String + var priority: Int + + init(tag: String, priority: Int) { + self.tag = tag // $ type=tag:String + self.priority = priority // $ type=priority:Int + } + + func display() -> String { + return tag // $ type=.tag:String + } + + func sortKey() -> Int { + return priority // $ type=.priority:Int + } +} + +func showAndSort(_ item: T) -> String { + return item.display() // $ target=Displayable2.display +} + +func showSortAndCompare(_ a: T, _ b: T) -> Bool +where T: Displayable2, T: Sortable, T: Equatable { + return a == b +} + +func testMultipleConstraints() { + let item = TaggedItem(tag: "x", priority: 1) // $ target=TaggedItem.init + let s = showAndSort(item) // $ type=s:String target=showAndSort(_:) + let eq = showSortAndCompare(item, item) // $ type=eq:Bool target=showSortAndCompare(_:_:) +} + +// --- Generic class with multiple constrained type parameters --- + +class SortedPair { + var first: T + var second: U + + init(first: T, second: U) { + self.first = first // $ type=first:T + self.second = second // $ type=second:U + } + + func isFirstSmaller(than other: T) -> Bool { + return first < other // $ type=other:T + } + + func isSecondSmaller(than other: U) -> Bool { + return second < other // $ type=other:U + } +} + +func testMultiConstrainedParams() { + let sp = SortedPair(first: 3, second: "b") // $ target=SortedPair.init + let r1 = sp.isFirstSmaller(than: 5) // $ type=r1:Bool target=SortedPair.isFirstSmaller + let r2 = sp.isSecondSmaller(than: "z") // $ type=r2:Bool target=SortedPair.isSecondSmaller +} + +// --- Associated type constraints (same-type constraint) --- + +protocol ElementContainer { + associatedtype Element + func first() -> Element +} + +struct IntArray: ElementContainer { + typealias Element = Int + var items: [Int] + + init(items: [Int]) { + self.items = items + } + + func first() -> Int { + return items[0] + } +} + +struct StringArray: ElementContainer { + typealias Element = String + var items: [String] + + init(items: [String]) { + self.items = items + } + + func first() -> String { + return items[0] + } +} + +func extractFirst(from container: C) -> C.Element where C.Element == Int { + return container.first() // $ target=ElementContainer.first +} + +func extractFirst(from container: C) -> C.Element where C.Element == String { + return container.first() // $ target=ElementContainer.first +} + +func testSameTypeConstraint() { + let ia = IntArray(items: [10, 20]) // $ target=IntArray.init + let sa = StringArray(items: ["hi", "there"]) // $ target=StringArray.init + let r1 = extractFirst(from: ia) // $ type=r1:Int target=extractFirst(from:Int) + let r2 = extractFirst(from: sa) // $ type=r2:String target=extractFirst(from:String) +} + +// --- Superclass constraint on type parameter --- + +class Vehicle { + var speed: Int + + init(speed: Int) { + self.speed = speed // $ type=speed:Int + } + + func describe() -> String { + return "vehicle" + } +} + +class Car: Vehicle { + override init(speed: Int) { + super.init(speed: speed) // $ target=Vehicle.init + } + + override func describe() -> String { + return "car" + } + + func honk() -> String { + return "beep" + } +} + +class Truck: Vehicle { + override init(speed: Int) { + super.init(speed: speed) // $ target=Vehicle.init + } + + override func describe() -> String { + return "truck" + } + + func haul() -> String { + return "hauling" + } +} + +func describeVehicle(_ v: T) -> String { + return v.describe() // $ target=Vehicle.describe +} + +func testSuperclassConstraint() { + let car = Car(speed: 100) // $ type=car:Car target=Car.init + let truck = Truck(speed: 60) // $ type=truck:Truck target=Truck.init + let d1 = describeVehicle(car) // $ type=d1:String target=describeVehicle(_:) + let d2 = describeVehicle(truck) // $ type=d2:String target=describeVehicle(_:) + let h = car.honk() // $ type=h:String target=Car.honk + let hl = truck.haul() // $ type=hl:String target=Truck.haul +} + +// --- Constrained extension methods --- + +protocol Summable { + static func + (lhs: Self, rhs: Self) -> Self +} + +extension Int: Summable {} +extension Double: Summable {} +extension String: Summable {} + +struct Accumulator { + var values: [T] + + init(values: [T]) { + self.values = values + } + + func count() -> Int { + return values.count + } +} + +extension Accumulator where T: Summable { + func total() -> T { + return values[0] + values[1] // $ target=Summable.+ + } +} + +extension Accumulator where T: Equatable { + func contains(_ item: T) -> Bool { + return values.contains(where: { $0 == item }) + } +} + +func testConstrainedExtensions() { + let intAcc = Accumulator(values: [1, 2, 3]) // $ target=Accumulator.init + let cnt = intAcc.count() // $ type=cnt:Int target=Accumulator.count + let tot = intAcc.total() // $ type=tot:Int target=Accumulator.total + let has = intAcc.contains(2) // $ type=has:Bool target=Accumulator.contains +} + +// --- Generic method with its own constrained type parameter --- + +class Transformer { + init() {} + + func transform(_ items: [T]) -> T { + return items[0] + items[1] // $ target=Summable.+ + } + + func merge(_ a: A, _ b: B) -> Bool { + return true + } +} + +func testMethodTypeParams() { + let t = Transformer() // $ target=Transformer.init + let r1 = t.transform([3, 1, 2]) // $ type=r1:Int target=Transformer.transform + let r2 = t.transform(["c", "a", "b"]) // $ type=r2:String target=Transformer.transform + let r3 = t.merge(1, "x") // $ type=r3:Bool target=Transformer.merge +} + +// --- Recursive constraint (Comparable requiring Equatable) --- + +func clamp(_ value: T, min lower: T, max upper: T) -> T { + if value < lower { return lower } + if value > upper { return upper } + return value +} + +func testRecursiveConstraint() { + let r1 = clamp(5, min: 0, max: 10) // $ type=r1:Int target=clamp(_:min:max:) + let r2 = clamp(3.5, min: 1.0, max: 2.0) // $ type=r2:Double target=clamp(_:min:max:) + let r3 = clamp("m", min: "a", max: "z") // $ type=r3:String target=clamp(_:min:max:) +} diff --git a/unified/tools/builtins/types.swift b/unified/tools/builtins/types.swift index 7a7d2e0c8c6a..c26a1878ecac 100644 --- a/unified/tools/builtins/types.swift +++ b/unified/tools/builtins/types.swift @@ -1,46 +1,55 @@ // Provides built-in Swift types -struct Bool { } +struct Bool {} -struct Int { } +struct Int {} -struct String { } +struct String { + public init(_ value: T) where T: LosslessStringConvertible { + fatalError("Dummy implementation.") + } +} -struct Character { } +struct Character {} -struct Substring { } +struct Substring {} -struct Int8 { } +struct Int8 {} -struct Int16 { } +struct Int16 {} -struct Int32 { } +struct Int32 {} -struct Int64 { } +struct Int64 {} -struct UInt { } +struct UInt {} -struct UInt8 { } +struct UInt8 {} -struct UInt16 { } +struct UInt16 {} -struct UInt32 { } +struct UInt32 {} -struct UInt64 { } +struct UInt64 {} -struct Float16 { } +struct Float16 {} -struct Float { } +struct Float {} -struct Double { } +struct Double {} -struct Float80 { } +struct Float80 {} -struct Array { } +struct Array { + public func map(_ transform: (Element) throws(E) -> T) throws(E) -> [T] + where E: Error { + fatalError("Dummy implementation.") + } +} -struct Dictionary { } +struct Dictionary {} -struct Set { } +struct Set {} enum Optional { case none @@ -52,41 +61,45 @@ enum Result { case failure(Failure) } -struct Range { } +struct Range {} -struct ClosedRange { } +struct ClosedRange {} -struct PartialRangeFrom { } +struct PartialRangeFrom {} -struct PartialRangeThrough { } +struct PartialRangeThrough {} -struct PartialRangeUpTo { } +struct PartialRangeUpTo {} -enum Never { } +enum Never {} -struct UnsafePointer { } +struct UnsafePointer {} -struct UnsafeMutablePointer { } +struct UnsafeMutablePointer {} -struct UnsafeRawPointer { } +struct UnsafeRawPointer {} -struct UnsafeMutableRawPointer { } +struct UnsafeMutableRawPointer {} -struct UnsafeBufferPointer { } +struct UnsafeBufferPointer {} -struct UnsafeMutableBufferPointer { } +struct UnsafeMutableBufferPointer {} -struct UnsafeRawBufferPointer { } +struct UnsafeRawBufferPointer {} -struct UnsafeMutableRawBufferPointer { } +struct UnsafeMutableRawBufferPointer {} -struct AutoreleasingUnsafeMutablePointer { } +struct AutoreleasingUnsafeMutablePointer {} -struct OpaquePointer { } +struct OpaquePointer {} -struct Unmanaged { } +struct Unmanaged {} -struct Function { } // `Args` is always instantiated as a tuple type +struct Function { // `Args` is always instantiated as a tuple type + public func invoke(args: Args) -> Return { + fatalError("Dummy implementation.") + } +} typealias Void = Tuple0