From cfb509abea39b0b59a1771abe0b55081023cdb04 Mon Sep 17 00:00:00 2001 From: thosakwe Date: Wed, 5 Jul 2017 18:44:13 -0400 Subject: [PATCH] Fixed disjoint spans --- lib/src/language/ast/alias.dart | 4 ++-- lib/src/language/ast/argument.dart | 6 +++--- lib/src/language/ast/array_value.dart | 8 +++++--- lib/src/language/ast/boolean_value.dart | 4 ++-- lib/src/language/ast/default_value.dart | 5 ++--- lib/src/language/ast/directive.dart | 14 ++++++++------ lib/src/language/ast/document.dart | 8 ++++---- lib/src/language/ast/field.dart | 14 +++++++------- lib/src/language/ast/field_name.dart | 4 ++-- lib/src/language/ast/fragment_definition.dart | 12 +++++++++--- lib/src/language/ast/fragment_spread.dart | 6 +++--- lib/src/language/ast/inline_fragment.dart | 9 ++++++--- lib/src/language/ast/list_type.dart | 5 ++--- lib/src/language/ast/node.dart | 2 +- lib/src/language/ast/number_value.dart | 2 +- lib/src/language/ast/operation_definition.dart | 8 +++++--- lib/src/language/ast/selection.dart | 4 ++-- lib/src/language/ast/selection_set.dart | 8 ++++---- lib/src/language/ast/string_value.dart | 3 +-- lib/src/language/ast/type.dart | 17 +++-------------- lib/src/language/ast/type_condition.dart | 4 ++-- lib/src/language/ast/type_name.dart | 4 ++-- lib/src/language/ast/value_or_variable.dart | 4 ++-- lib/src/language/ast/variable.dart | 6 +++--- lib/src/language/ast/variable_definition.dart | 5 ++--- lib/src/language/ast/variable_definitions.dart | 13 ++++++++----- lib/src/language/token.dart | 2 +- pubspec.yaml | 2 +- test/argument_test.dart | 1 + test/document_test.dart | 1 + 30 files changed, 95 insertions(+), 90 deletions(-) diff --git a/lib/src/language/ast/alias.dart b/lib/src/language/ast/alias.dart index 2400b378..9517cf15 100644 --- a/lib/src/language/ast/alias.dart +++ b/lib/src/language/ast/alias.dart @@ -1,6 +1,6 @@ import '../token.dart'; import 'node.dart'; -import 'package:source_span/src/span.dart'; +import 'package:source_span/source_span.dart'; class AliasContext extends Node { final Token NAME1, COLON, NAME2; @@ -14,7 +14,7 @@ class AliasContext extends Node { String get name => NAME2.text; @override - SourceSpan get span => NAME1.span.union(COLON.span).union(NAME2.span); + FileSpan get span => NAME1.span.expand(COLON.span).expand(NAME2.span); @override String toSource() => '${NAME1.text}:${NAME2.text}'; diff --git a/lib/src/language/ast/argument.dart b/lib/src/language/ast/argument.dart index 44bc0122..f2b56c86 100644 --- a/lib/src/language/ast/argument.dart +++ b/lib/src/language/ast/argument.dart @@ -1,6 +1,6 @@ +import 'package:source_span/source_span.dart'; import '../token.dart'; import 'node.dart'; -import 'package:source_span/src/span.dart'; import 'value_or_variable.dart'; class ArgumentContext extends Node { @@ -12,8 +12,8 @@ class ArgumentContext extends Node { String get name => NAME.text; @override - SourceSpan get span => - NAME.span.union(COLON.span).union(valueOrVariable.span); + FileSpan get span => + NAME.span.expand(COLON.span).expand(valueOrVariable.span); @override String toSource() => '${NAME.text}:${valueOrVariable.toSource()}'; diff --git a/lib/src/language/ast/array_value.dart b/lib/src/language/ast/array_value.dart index 4cacda1a..8fe28e72 100644 --- a/lib/src/language/ast/array_value.dart +++ b/lib/src/language/ast/array_value.dart @@ -1,5 +1,5 @@ +import 'package:source_span/source_span.dart'; import '../token.dart'; -import 'package:source_span/src/span.dart'; import 'value.dart'; class ArrayValueContext extends ValueContext { @@ -9,8 +9,10 @@ class ArrayValueContext extends ValueContext { ArrayValueContext(this.LBRACKET, this.RBRACKET); @override - SourceSpan get span => - new SourceSpan(LBRACKET.span?.end, RBRACKET.span?.end, toSource()); + FileSpan get span { + var out = values.fold(LBRACKET.span, (o, v) => o.expand(v.span)); + return out.expand(RBRACKET.span); + } @override List get value => values.map((v) => v.value).toList(); diff --git a/lib/src/language/ast/boolean_value.dart b/lib/src/language/ast/boolean_value.dart index 7f74ac08..5b6e75b8 100644 --- a/lib/src/language/ast/boolean_value.dart +++ b/lib/src/language/ast/boolean_value.dart @@ -1,5 +1,5 @@ import '../token.dart'; -import 'package:source_span/src/span.dart'; +import 'package:source_span/source_span.dart'; import 'value.dart'; class BooleanValueContext extends ValueContext { @@ -16,7 +16,7 @@ class BooleanValueContext extends ValueContext { get value => booleanValue; @override - SourceSpan get span => BOOLEAN.span; + FileSpan get span => BOOLEAN.span; @override String toSource() => BOOLEAN.text; diff --git a/lib/src/language/ast/default_value.dart b/lib/src/language/ast/default_value.dart index 911b920b..3519db53 100644 --- a/lib/src/language/ast/default_value.dart +++ b/lib/src/language/ast/default_value.dart @@ -1,6 +1,6 @@ import '../token.dart'; import 'node.dart'; -import 'package:source_span/src/span.dart'; +import 'package:source_span/source_span.dart'; import 'value.dart'; class DefaultValueContext extends Node { @@ -10,8 +10,7 @@ class DefaultValueContext extends Node { DefaultValueContext(this.EQUALS, this.value); @override - SourceSpan get span => - new SourceSpan(EQUALS.span?.start, value.end, toSource()); + FileSpan get span => EQUALS.span.expand(value.span); @override String toSource() => '=${value.toSource()}'; diff --git a/lib/src/language/ast/directive.dart b/lib/src/language/ast/directive.dart index f8950dc2..a86179fc 100644 --- a/lib/src/language/ast/directive.dart +++ b/lib/src/language/ast/directive.dart @@ -15,14 +15,16 @@ class DirectiveContext extends Node { } @override - SourceSpan get span { - SourceLocation end = NAME.span?.end; + FileSpan get span { + var out = ARROBA.span.expand(NAME.span); - if (valueOrVariable != null) - end = valueOrVariable.end; - else if (RPAREN != null) end = RPAREN.span?.end; + if (COLON != null) { + out = out.expand(COLON.span).expand(valueOrVariable.span); + } else if (LPAREN != null) { + out = out.expand(LPAREN.span).expand(argument.span).expand(RPAREN.span); + } - return new SourceSpan(ARROBA.span?.start, end, toSource()); + return out; } @override diff --git a/lib/src/language/ast/document.dart b/lib/src/language/ast/document.dart index 6152c39e..526911dd 100644 --- a/lib/src/language/ast/document.dart +++ b/lib/src/language/ast/document.dart @@ -1,16 +1,16 @@ +import 'package:source_span/source_span.dart'; import 'definition.dart'; import 'node.dart'; -import 'package:source_span/src/span.dart'; class DocumentContext extends Node { final List definitions = []; @override - SourceSpan get span { + FileSpan get span { if (definitions.isEmpty) return null; return definitions - .map((d) => d.span) - .reduce((a, b) => a.union(b)); + .map((d) => d.span) + .reduce((a, b) => a.expand(b)); } @override diff --git a/lib/src/language/ast/field.dart b/lib/src/language/ast/field.dart index 7a3f4ebc..e035e58a 100644 --- a/lib/src/language/ast/field.dart +++ b/lib/src/language/ast/field.dart @@ -1,8 +1,8 @@ +import 'package:source_span/source_span.dart'; import 'argument.dart'; import 'directive.dart'; import 'field_name.dart'; import 'node.dart'; -import 'package:source_span/source_span.dart'; import 'selection_set.dart'; class FieldContext extends Node { @@ -14,15 +14,15 @@ class FieldContext extends Node { FieldContext(this.fieldName, [this.selectionSet]); @override - SourceSpan get span { + FileSpan get span { if (selectionSet != null) - return fieldName.span.union(selectionSet.span); + return fieldName.span.expand(selectionSet.span); else if (directives.isNotEmpty) - return directives.fold( - fieldName.span, (out, d) => out.union(d.span)); + return directives.fold( + fieldName.span, (out, d) => out.expand(d.span)); if (arguments.isNotEmpty) - return arguments.fold( - fieldName.span, (out, a) => out.union(a.span)); + return arguments.fold( + fieldName.span, (out, a) => out.expand(a.span)); else return fieldName.span; } diff --git a/lib/src/language/ast/field_name.dart b/lib/src/language/ast/field_name.dart index d32afa77..87083a2f 100644 --- a/lib/src/language/ast/field_name.dart +++ b/lib/src/language/ast/field_name.dart @@ -1,7 +1,7 @@ +import 'package:source_span/source_span.dart'; import '../token.dart'; import 'alias.dart'; import 'node.dart'; -import 'package:source_span/src/span.dart'; class FieldNameContext extends Node { final Token NAME; @@ -14,7 +14,7 @@ class FieldNameContext extends Node { String get name => NAME?.text; @override - SourceSpan get span => alias?.span ?? NAME.span; + FileSpan get span => alias?.span ?? NAME.span; @override String toSource() => alias?.toSource() ?? NAME.text; diff --git a/lib/src/language/ast/fragment_definition.dart b/lib/src/language/ast/fragment_definition.dart index 22b6c744..530efdcc 100644 --- a/lib/src/language/ast/fragment_definition.dart +++ b/lib/src/language/ast/fragment_definition.dart @@ -1,7 +1,7 @@ import '../token.dart'; import 'definition.dart'; import 'directive.dart'; -import 'package:source_span/src/span.dart'; +import 'package:source_span/source_span.dart'; import 'selection_set.dart'; import 'type_condition.dart'; @@ -17,8 +17,14 @@ class FragmentDefinitionContext extends DefinitionContext { this.FRAGMENT, this.NAME, this.ON, this.typeCondition, this.selectionSet); @override - SourceSpan get span => - new SourceSpan(FRAGMENT.span?.start, selectionSet.end, toSource()); + FileSpan get span { + var out = FRAGMENT.span + .expand(NAME.span) + .expand(ON.span) + .expand(typeCondition.span); + out = directives.fold(out, (o, d) => o.expand(d.span)); + return out.expand(selectionSet.span); + } @override String toSource() => diff --git a/lib/src/language/ast/fragment_spread.dart b/lib/src/language/ast/fragment_spread.dart index c6582ba8..69aa0e5e 100644 --- a/lib/src/language/ast/fragment_spread.dart +++ b/lib/src/language/ast/fragment_spread.dart @@ -12,10 +12,10 @@ class FragmentSpreadContext extends Node { String get name => NAME.text; @override - SourceSpan get span { - var out = ELLIPSIS.span.union(NAME.span); + FileSpan get span { + var out = ELLIPSIS.span.expand(NAME.span); if (directives.isEmpty) return out; - return directives.fold(out, (o, d) => o.union(d.span)); + return directives.fold(out, (o, d) => o.expand(d.span)); } @override diff --git a/lib/src/language/ast/inline_fragment.dart b/lib/src/language/ast/inline_fragment.dart index 3b9b61b5..a9ad43a2 100644 --- a/lib/src/language/ast/inline_fragment.dart +++ b/lib/src/language/ast/inline_fragment.dart @@ -1,7 +1,7 @@ import '../token.dart'; import 'directive.dart'; import 'node.dart'; -import 'package:source_span/src/span.dart'; +import 'package:source_span/source_span.dart'; import 'selection_set.dart'; import 'type_condition.dart'; @@ -15,8 +15,11 @@ class InlineFragmentContext extends Node { this.ELLIPSIS, this.ON, this.typeCondition, this.selectionSet); @override - SourceSpan get span => - new SourceSpan(ELLIPSIS.span?.start, selectionSet.end, toSource()); + FileSpan get span { + var out = ELLIPSIS.span.expand(ON.span).expand(typeCondition.span); + out = directives.fold(out, (o, d) => o.expand(d.span)); + return out.expand(selectionSet.span); + } @override String toSource() => diff --git a/lib/src/language/ast/list_type.dart b/lib/src/language/ast/list_type.dart index 09c635aa..a5697a22 100644 --- a/lib/src/language/ast/list_type.dart +++ b/lib/src/language/ast/list_type.dart @@ -1,6 +1,6 @@ import '../token.dart'; import 'node.dart'; -import 'package:source_span/src/span.dart'; +import 'package:source_span/source_span.dart'; import 'type.dart'; class ListTypeContext extends Node { @@ -10,8 +10,7 @@ class ListTypeContext extends Node { ListTypeContext(this.LBRACKET, this.type, this.RBRACKET); @override - SourceSpan get span => - new SourceSpan(LBRACKET.span?.end, RBRACKET.span?.end, toSource()); + FileSpan get span => LBRACKET.span.expand(type.span).expand(RBRACKET.span); @override String toSource() => '[${type.toSource()}]'; diff --git a/lib/src/language/ast/node.dart b/lib/src/language/ast/node.dart index 1b6bebfe..aa6aacbd 100644 --- a/lib/src/language/ast/node.dart +++ b/lib/src/language/ast/node.dart @@ -1,7 +1,7 @@ import 'package:source_span/source_span.dart'; abstract class Node { - SourceSpan get span; + FileSpan get span; SourceLocation get start => span.start; SourceLocation get end => span.end; diff --git a/lib/src/language/ast/number_value.dart b/lib/src/language/ast/number_value.dart index 7d6db952..21247606 100644 --- a/lib/src/language/ast/number_value.dart +++ b/lib/src/language/ast/number_value.dart @@ -24,7 +24,7 @@ class NumberValueContext extends ValueContext { get value => numberValue; @override - SourceSpan get span => NUMBER.span; + FileSpan get span => NUMBER.span; @override String toSource() => NUMBER.text; diff --git a/lib/src/language/ast/operation_definition.dart b/lib/src/language/ast/operation_definition.dart index ebc6ab65..5333c5e6 100644 --- a/lib/src/language/ast/operation_definition.dart +++ b/lib/src/language/ast/operation_definition.dart @@ -1,7 +1,7 @@ import '../token.dart'; import 'definition.dart'; import 'directive.dart'; -import 'package:source_span/src/span.dart'; +import 'package:source_span/source_span.dart'; import 'selection_set.dart'; import 'variable_definitions.dart'; @@ -22,9 +22,11 @@ class OperationDefinitionContext extends DefinitionContext { } @override - SourceSpan get span { + FileSpan get span { if (TYPE == null) return selectionSet.span; - return new SourceSpan(TYPE.span?.start, selectionSet.end, toSource()); + var out = TYPE.span.expand(NAME.span); + out = directives.fold(out, (o, d) => o.expand(d.span)); + return out.expand(selectionSet.span); } @override diff --git a/lib/src/language/ast/selection.dart b/lib/src/language/ast/selection.dart index b1299828..e573bb9f 100644 --- a/lib/src/language/ast/selection.dart +++ b/lib/src/language/ast/selection.dart @@ -2,7 +2,7 @@ import 'field.dart'; import 'fragment_spread.dart'; import 'inline_fragment.dart'; import 'node.dart'; -import 'package:source_span/src/span.dart'; +import 'package:source_span/source_span.dart'; class SelectionContext extends Node { final FieldContext field; @@ -14,7 +14,7 @@ class SelectionContext extends Node { } @override - SourceSpan get span => + FileSpan get span => field?.span ?? fragmentSpread?.span ?? inlineFragment?.span; @override diff --git a/lib/src/language/ast/selection_set.dart b/lib/src/language/ast/selection_set.dart index 936d9855..0ce60570 100644 --- a/lib/src/language/ast/selection_set.dart +++ b/lib/src/language/ast/selection_set.dart @@ -1,6 +1,6 @@ +import 'package:source_span/source_span.dart'; import '../token.dart'; import 'node.dart'; -import 'package:source_span/src/span.dart'; import 'selection.dart'; class SelectionSetContext extends Node { @@ -10,10 +10,10 @@ class SelectionSetContext extends Node { SelectionSetContext(this.LBRACE, this.RBRACE); @override - SourceSpan get span { + FileSpan get span { var out = - selections.fold(LBRACE.span, (out, s) => out.union(s.span)); - return out.union(RBRACE.span); + selections.fold(LBRACE.span, (out, s) => out.expand(s.span)); + return out.expand(RBRACE.span); } @override diff --git a/lib/src/language/ast/string_value.dart b/lib/src/language/ast/string_value.dart index 97ba0435..d10a4664 100644 --- a/lib/src/language/ast/string_value.dart +++ b/lib/src/language/ast/string_value.dart @@ -1,4 +1,3 @@ -import 'dart:convert'; import 'package:charcode/charcode.dart'; import 'package:source_span/source_span.dart'; import '../syntax_error.dart'; @@ -11,7 +10,7 @@ class StringValueContext extends ValueContext { StringValueContext(this.STRING); @override - SourceSpan get span => STRING.span; + FileSpan get span => STRING.span; String get stringValue { var text = STRING.text.substring(1, STRING.text.length - 1); diff --git a/lib/src/language/ast/type.dart b/lib/src/language/ast/type.dart index 2f64e18d..8adadadf 100644 --- a/lib/src/language/ast/type.dart +++ b/lib/src/language/ast/type.dart @@ -16,20 +16,9 @@ class TypeContext extends Node { } @override - SourceSpan get span { - SourceLocation start, end; - - if (typeName != null) { - start = typeName.start; - end = typeName.end; - } else if (listType != null) { - start = listType.start; - end = listType.end; - } - - if (EXCLAMATION != null) end = EXCLAMATION.span?.end; - - return new SourceSpan(start, end, toSource()); + FileSpan get span { + var out = typeName?.span ?? listType.span; + return EXCLAMATION != null ? out.expand(EXCLAMATION.span) : out; } @override diff --git a/lib/src/language/ast/type_condition.dart b/lib/src/language/ast/type_condition.dart index 5acc5c7f..c555b534 100644 --- a/lib/src/language/ast/type_condition.dart +++ b/lib/src/language/ast/type_condition.dart @@ -1,5 +1,5 @@ import 'node.dart'; -import 'package:source_span/src/span.dart'; +import 'package:source_span/source_span.dart'; import 'type_name.dart'; class TypeConditionContext extends Node { @@ -8,7 +8,7 @@ class TypeConditionContext extends Node { TypeConditionContext(this.typeName); @override - SourceSpan get span => typeName.span; + FileSpan get span => typeName.span; @override String toSource() => typeName.toSource(); diff --git a/lib/src/language/ast/type_name.dart b/lib/src/language/ast/type_name.dart index 89429e88..7ee3906c 100644 --- a/lib/src/language/ast/type_name.dart +++ b/lib/src/language/ast/type_name.dart @@ -1,5 +1,5 @@ import 'node.dart'; -import 'package:source_span/src/span.dart'; +import 'package:source_span/source_span.dart'; import '../token.dart'; class TypeNameContext extends Node { @@ -8,7 +8,7 @@ class TypeNameContext extends Node { String get name => NAME.text; @override - SourceSpan get span => NAME.span; + FileSpan get span => NAME.span; TypeNameContext(this.NAME); diff --git a/lib/src/language/ast/value_or_variable.dart b/lib/src/language/ast/value_or_variable.dart index d2ebb1be..3cd64c5d 100644 --- a/lib/src/language/ast/value_or_variable.dart +++ b/lib/src/language/ast/value_or_variable.dart @@ -1,5 +1,5 @@ import 'node.dart'; -import 'package:source_span/src/span.dart'; +import 'package:source_span/source_span.dart'; import 'value.dart'; import 'variable.dart'; @@ -12,7 +12,7 @@ class ValueOrVariableContext extends Node { } @override - SourceSpan get span => value?.span ?? variable.span; + FileSpan get span => value?.span ?? variable.span; @override String toSource() => '${value?.toSource() ?? variable.toSource()}'; diff --git a/lib/src/language/ast/variable.dart b/lib/src/language/ast/variable.dart index b1fbb439..a87476c3 100644 --- a/lib/src/language/ast/variable.dart +++ b/lib/src/language/ast/variable.dart @@ -1,6 +1,6 @@ import '../token.dart'; import 'node.dart'; -import 'package:source_span/src/span.dart'; +import 'package:source_span/source_span.dart'; class VariableContext extends Node { final Token DOLLAR, NAME; @@ -10,8 +10,8 @@ class VariableContext extends Node { String get name => NAME.text; @override - SourceSpan get span => DOLLAR.span.union(NAME.span); - // new SourceSpan(DOLLAR?.span?.start, NAME?.span?.end, toSource()); + FileSpan get span => DOLLAR.span.expand(NAME.span); + // new FileSpan(DOLLAR?.span?.start, NAME?.span?.end, toSource()); @override String toSource() => '\$${NAME.text}'; diff --git a/lib/src/language/ast/variable_definition.dart b/lib/src/language/ast/variable_definition.dart index 1f5396f4..f03afba9 100644 --- a/lib/src/language/ast/variable_definition.dart +++ b/lib/src/language/ast/variable_definition.dart @@ -1,7 +1,7 @@ import '../token.dart'; import 'node.dart'; import 'default_value.dart'; -import 'package:source_span/src/span.dart'; +import 'package:source_span/source_span.dart'; import 'type.dart'; import 'variable.dart'; @@ -15,8 +15,7 @@ class VariableDefinitionContext extends Node { [this.defaultValue]); @override - SourceSpan get span => - new SourceSpan(variable.start, defaultValue?.end ?? type.end, toSource()); + FileSpan get span => variable.span.expand(defaultValue?.span ?? type.span); @override String toSource() => diff --git a/lib/src/language/ast/variable_definitions.dart b/lib/src/language/ast/variable_definitions.dart index 91008531..81f3113e 100644 --- a/lib/src/language/ast/variable_definitions.dart +++ b/lib/src/language/ast/variable_definitions.dart @@ -1,6 +1,6 @@ import '../token.dart'; import 'node.dart'; -import 'package:source_span/src/span.dart'; +import 'package:source_span/source_span.dart'; import 'variable_definition.dart'; class VariableDefinitionsContext extends Node { @@ -10,19 +10,22 @@ class VariableDefinitionsContext extends Node { VariableDefinitionsContext(this.LPAREN, this.RPAREN); @override - SourceSpan get span => - new SourceSpan(LPAREN.span?.end, RPAREN.span?.end, toSource()); + FileSpan get span { + var out = variableDefinitions.fold( + LPAREN.span, (o, v) => o.expand(v.span)); + return out.expand(RPAREN.span); + } @override String toSource() { - var buf = new StringBuffer('['); + var buf = new StringBuffer('('); for (int i = 0; i < variableDefinitions.length; i++) { if (i > 0) buf.write(','); buf.write(variableDefinitions[i].toSource()); } - buf.write(']'); + buf.write(')'); return buf.toString(); } } diff --git a/lib/src/language/token.dart b/lib/src/language/token.dart index c7cee1a2..5d12c90d 100644 --- a/lib/src/language/token.dart +++ b/lib/src/language/token.dart @@ -4,7 +4,7 @@ import 'token_type.dart'; class Token { final TokenType type; final String text; - SourceSpan span; + FileSpan span; Token(this.type, this.text, [this.span]); diff --git a/pubspec.yaml b/pubspec.yaml index 683983be..c2ff0ef4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: graphql_parser -version: 1.0.0 +version: 1.0.0+1 description: Parses GraphQL queries and schemas. author: Tobe O homepage: https://github.com/thosakwe/graphql_parser diff --git a/test/argument_test.dart b/test/argument_test.dart index cbd510b4..92048c42 100644 --- a/test/argument_test.dart +++ b/test/argument_test.dart @@ -39,6 +39,7 @@ class _IsArgument extends Matcher { bool matches(item, Map matchState) { var arg = item is ArgumentContext ? item : parseArgument(item); if (arg == null) return false; + print(arg.toSource()); return equals(name).matches(arg.name, matchState) && equals(value).matches( arg.valueOrVariable.value?.value ?? diff --git a/test/document_test.dart b/test/document_test.dart index 013cddf9..d2c1f9b7 100644 --- a/test/document_test.dart +++ b/test/document_test.dart @@ -63,6 +63,7 @@ main() { var doc = parse(r'query foo ($one: [int] = 2) @foo @bar: 2 {foo, bar: baz}') .parseDocument(); + print(doc.toSource()); expect(doc.definitions, hasLength(1)); expect(doc.definitions.first, const isInstanceOf());