From 089e1ba737b5b505d4c0e02145c7e34191b79452 Mon Sep 17 00:00:00 2001 From: Konstantin Shcheglov Date: Tue, 1 Mar 2016 21:04:17 -0800 Subject: [PATCH] Add codeOffset/codeLength properties to ElementImpl. R=brianwilkerson@google.com BUG= Review URL: https://codereview.chromium.org/1753963003 . --- .../lib/src/dart/element/builder.dart | 40 +++++++++- .../lib/src/dart/element/element.dart | 48 ++++++++++++ .../test/generated/all_the_rest_test.dart | 76 ++++++++++++++++++- 3 files changed, 160 insertions(+), 4 deletions(-) diff --git a/pkg/analyzer/lib/src/dart/element/builder.dart b/pkg/analyzer/lib/src/dart/element/builder.dart index 48a732f47f28..23869eeb038f 100644 --- a/pkg/analyzer/lib/src/dart/element/builder.dart +++ b/pkg/analyzer/lib/src/dart/element/builder.dart @@ -382,6 +382,7 @@ class ElementBuilder extends RecursiveAstVisitor { if (stackTraceParameter != null) { LocalVariableElementImpl stackTrace = new LocalVariableElementImpl.forNode(stackTraceParameter); + _setCodeRange(stackTrace, stackTraceParameter); _currentHolder.addLocalVariable(stackTrace); stackTraceParameter.staticElement = stackTrace; } @@ -413,6 +414,7 @@ class ElementBuilder extends RecursiveAstVisitor { } SimpleIdentifier className = node.name; ClassElementImpl element = new ClassElementImpl.forNode(className); + _setCodeRange(element, node); element.metadata = _createElementAnnotations(node.metadata); List typeParameters = holder.typeParameters; List typeArguments = _createTypeParameterTypes(typeParameters); @@ -462,6 +464,7 @@ class ElementBuilder extends RecursiveAstVisitor { _visitChildren(holder, node); SimpleIdentifier className = node.name; ClassElementImpl element = new ClassElementImpl.forNode(className); + _setCodeRange(element, node); element.metadata = _createElementAnnotations(node.metadata); element.abstract = node.abstractKeyword != null; element.mixinApplication = true; @@ -478,6 +481,14 @@ class ElementBuilder extends RecursiveAstVisitor { return null; } + @override + Object visitCompilationUnit(CompilationUnit node) { + if (compilationUnitElement is ElementImpl) { + _setCodeRange(compilationUnitElement as ElementImpl, node); + } + return super.visitCompilationUnit(node); + } + @override Object visitConstructorDeclaration(ConstructorDeclaration node) { ElementHolder holder = new ElementHolder(); @@ -492,6 +503,7 @@ class ElementBuilder extends RecursiveAstVisitor { SimpleIdentifier constructorName = node.name; ConstructorElementImpl element = new ConstructorElementImpl.forNode(constructorName); + _setCodeRange(element, node); element.metadata = _createElementAnnotations(node.metadata); setElementDocumentationComment(element, node); if (node.externalKeyword != null) { @@ -533,6 +545,7 @@ class ElementBuilder extends RecursiveAstVisitor { SimpleIdentifier variableName = node.identifier; LocalVariableElementImpl element = new LocalVariableElementImpl.forNode(variableName); + _setCodeRange(element, node); element.metadata = _createElementAnnotations(node.metadata); ForEachStatement statement = node.parent as ForEachStatement; int declarationEnd = node.offset + node.length; @@ -565,6 +578,7 @@ class ElementBuilder extends RecursiveAstVisitor { } else { parameter = new DefaultParameterElementImpl.forNode(parameterName); } + _setCodeRange(parameter, node); parameter.const3 = node.isConst; parameter.final2 = node.isFinal; parameter.parameterKind = node.kind; @@ -601,6 +615,7 @@ class ElementBuilder extends RecursiveAstVisitor { Object visitEnumDeclaration(EnumDeclaration node) { SimpleIdentifier enumName = node.name; ClassElementImpl enumElement = new ClassElementImpl.forNode(enumName); + _setCodeRange(enumElement, node); enumElement.metadata = _createElementAnnotations(node.metadata); enumElement.enum2 = true; setElementDocumentationComment(enumElement, node); @@ -630,6 +645,7 @@ class ElementBuilder extends RecursiveAstVisitor { _fieldMap == null ? null : _fieldMap[parameterName.name]; FieldFormalParameterElementImpl parameter = new FieldFormalParameterElementImpl.forNode(parameterName); + _setCodeRange(parameter, node); parameter.const3 = node.isConst; parameter.final2 = node.isFinal; parameter.parameterKind = node.kind; @@ -671,6 +687,7 @@ class ElementBuilder extends RecursiveAstVisitor { SimpleIdentifier functionName = node.name; FunctionElementImpl element = new FunctionElementImpl.forNode(functionName); + _setCodeRange(element, node); element.metadata = _createElementAnnotations(node.metadata); setElementDocumentationComment(element, node); if (node.externalKeyword != null) { @@ -718,6 +735,7 @@ class ElementBuilder extends RecursiveAstVisitor { if (node.isGetter) { PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.forNode(propertyNameNode); + _setCodeRange(getter, node); getter.metadata = _createElementAnnotations(node.metadata); setElementDocumentationComment(getter, node); if (node.externalKeyword != null) { @@ -745,6 +763,7 @@ class ElementBuilder extends RecursiveAstVisitor { } else { PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.forNode(propertyNameNode); + _setCodeRange(setter, node); setter.metadata = _createElementAnnotations(node.metadata); setElementDocumentationComment(setter, node); if (node.externalKeyword != null) { @@ -796,6 +815,7 @@ class ElementBuilder extends RecursiveAstVisitor { FunctionBody body = node.body; FunctionElementImpl element = new FunctionElementImpl.forOffset(node.beginToken.offset); + _setCodeRange(element, node); element.functions = holder.functions; element.labels = holder.labels; element.localVariables = holder.localVariables; @@ -834,6 +854,7 @@ class ElementBuilder extends RecursiveAstVisitor { List typeParameters = holder.typeParameters; FunctionTypeAliasElementImpl element = new FunctionTypeAliasElementImpl.forNode(aliasName); + _setCodeRange(element, node); element.metadata = _createElementAnnotations(node.metadata); setElementDocumentationComment(element, node); element.parameters = parameters; @@ -852,6 +873,7 @@ class ElementBuilder extends RecursiveAstVisitor { SimpleIdentifier parameterName = node.identifier; ParameterElementImpl parameter = new ParameterElementImpl.forNode(parameterName); + _setCodeRange(parameter, node); parameter.parameterKind = node.kind; _setParameterVisibleRange(node, parameter); _currentHolder.addParameter(parameter); @@ -884,6 +906,7 @@ class ElementBuilder extends RecursiveAstVisitor { SimpleIdentifier labelName = label.label; LabelElementImpl element = new LabelElementImpl.forNode(labelName, onSwitchStatement, false); + _setCodeRange(element, node); _currentHolder.addLabel(element); labelName.staticElement = element; } @@ -919,6 +942,7 @@ class ElementBuilder extends RecursiveAstVisitor { } MethodElementImpl element = new MethodElementImpl(nameOfMethod, methodName.offset); + _setCodeRange(element, node); element.metadata = _createElementAnnotations(node.metadata); setElementDocumentationComment(element, node); element.abstract = node.isAbstract; @@ -957,6 +981,7 @@ class ElementBuilder extends RecursiveAstVisitor { if (node.isGetter) { PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.forNode(propertyNameNode); + _setCodeRange(getter, node); getter.metadata = _createElementAnnotations(node.metadata); setElementDocumentationComment(getter, node); if (node.externalKeyword != null) { @@ -984,6 +1009,7 @@ class ElementBuilder extends RecursiveAstVisitor { } else { PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.forNode(propertyNameNode); + _setCodeRange(setter, node); setter.metadata = _createElementAnnotations(node.metadata); setElementDocumentationComment(setter, node); if (node.externalKeyword != null) { @@ -1062,6 +1088,7 @@ class ElementBuilder extends RecursiveAstVisitor { SimpleIdentifier parameterName = node.identifier; ParameterElementImpl parameter = new ParameterElementImpl.forNode(parameterName); + _setCodeRange(parameter, node); parameter.const3 = node.isConst; parameter.final2 = node.isFinal; parameter.parameterKind = node.kind; @@ -1107,6 +1134,7 @@ class ElementBuilder extends RecursiveAstVisitor { SimpleIdentifier parameterName = node.name; TypeParameterElementImpl typeParameter = new TypeParameterElementImpl.forNode(parameterName); + _setCodeRange(typeParameter, node); typeParameter.metadata = _createElementAnnotations(node.metadata); TypeParameterTypeImpl typeParameterType = new TypeParameterTypeImpl(typeParameter); @@ -1135,6 +1163,7 @@ class ElementBuilder extends RecursiveAstVisitor { } element = field; field.static = fieldNode.isStatic; + _setCodeRange(element, node); setElementDocumentationComment(element, fieldNode); field.hasImplicitType = varList.type == null; _currentHolder.addField(field); @@ -1148,6 +1177,7 @@ class ElementBuilder extends RecursiveAstVisitor { variable = new LocalVariableElementImpl.forNode(variableName); } element = variable; + _setCodeRange(element, node); Block enclosingBlock = node.getAncestor((node) => node is Block); // TODO(brianwilkerson) This isn't right for variables declared in a for // loop. @@ -1164,6 +1194,7 @@ class ElementBuilder extends RecursiveAstVisitor { variable = new TopLevelVariableElementImpl.forNode(variableName); } element = variable; + _setCodeRange(element, node); if (varList.parent is TopLevelVariableDeclaration) { setElementDocumentationComment(element, varList.parent); } @@ -1226,8 +1257,9 @@ class ElementBuilder extends RecursiveAstVisitor { elementAnnotations = _createElementAnnotations(node.metadata); } for (VariableDeclaration variableDeclaration in node.variables) { - (variableDeclaration.element as ElementImpl).metadata = - elementAnnotations; + ElementImpl element = variableDeclaration.element as ElementImpl; + _setCodeRange(element, node.parent); + element.metadata = elementAnnotations; } return null; } @@ -1319,6 +1351,10 @@ class ElementBuilder extends RecursiveAstVisitor { return null; } + void _setCodeRange(ElementImpl element, AstNode node) { + element.setCodeRange(node.offset, node.length); + } + /** * Sets the visible source range for formal parameter. */ diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart index 55c22fc33be7..e3f4dfeeab2c 100644 --- a/pkg/analyzer/lib/src/dart/element/element.dart +++ b/pkg/analyzer/lib/src/dart/element/element.dart @@ -1734,6 +1734,17 @@ abstract class ElementImpl implements Element { */ int _docRangeLength; + /** + * The offset of the beginning of the element's code in the file that contains + * the element, or `null` if the element is synthetic. + */ + int _codeOffset; + + /** + * The length of the element's code, or `null` if the element is synthetic. + */ + int _codeLength; + /** * Initialize a newly created element to have the given [name] at the given * [_nameOffset]. @@ -1748,6 +1759,17 @@ abstract class ElementImpl implements Element { ElementImpl.forNode(Identifier name) : this(name == null ? "" : name.name, name == null ? -1 : name.offset); + /** + * The length of the element's code, or `null` if the element is synthetic. + */ + int get codeLength => _codeLength; + + /** + * The offset of the beginning of the element's code in the file that contains + * the element, or `null` if the element is synthetic. + */ + int get codeOffset => _codeOffset; + @override AnalysisContext get context { if (_enclosingElement == null) { @@ -2027,6 +2049,14 @@ abstract class ElementImpl implements Element { } } + /** + * Set the code range for this element. + */ + void setCodeRange(int offset, int length) { + _codeOffset = offset; + _codeLength = length; + } + /** * Set the documentation comment source range for this element. */ @@ -3106,6 +3136,24 @@ class LibraryElementImpl extends ElementImpl implements LibraryElement { : super.forNode(name), nameLength = name != null ? name.length : 0; + @override + int get codeLength { + if (_definingCompilationUnit is CompilationUnitElementImpl) { + return (_definingCompilationUnit as CompilationUnitElementImpl) + .codeLength; + } + return null; + } + + @override + int get codeOffset { + if (_definingCompilationUnit is CompilationUnitElementImpl) { + return (_definingCompilationUnit as CompilationUnitElementImpl) + .codeOffset; + } + return null; + } + @override CompilationUnitElement get definingCompilationUnit => _definingCompilationUnit; diff --git a/pkg/analyzer/test/generated/all_the_rest_test.dart b/pkg/analyzer/test/generated/all_the_rest_test.dart index 5d74e2c67b46..b7ed4b37a700 100644 --- a/pkg/analyzer/test/generated/all_the_rest_test.dart +++ b/pkg/analyzer/test/generated/all_the_rest_test.dart @@ -660,6 +660,7 @@ class C { AstFactory.classDeclaration(null, className, null, null, null, null); classDeclaration.documentationComment = AstFactory.documentationComment( [TokenFactory.tokenFromString('/// aaa')..offset = 50], []); + classDeclaration.endToken.offset = 80; classDeclaration.accept(builder); List types = holder.types; expect(types, hasLength(1)); @@ -673,6 +674,7 @@ class C { expect(type.isSynthetic, isFalse); expect(type.documentationComment, '/// aaa'); _assertHasDocRange(type, 50, 7); + _assertHasCodeRange(type, 50, 31); } void test_visitClassDeclaration_parameterized() { @@ -837,6 +839,26 @@ class C { expect(type.typeParameters[0].name, equals('T')); } + void test_visitCompilationUnit_codeRange() { + TopLevelVariableDeclaration topLevelVariableDeclaration = AstFactory + .topLevelVariableDeclaration(null, AstFactory.typeName4('int'), + [AstFactory.variableDeclaration('V')]); + CompilationUnit unit = new CompilationUnit( + topLevelVariableDeclaration.beginToken, + null, + [], + [topLevelVariableDeclaration], + topLevelVariableDeclaration.endToken); + ElementHolder holder = new ElementHolder(); + ElementBuilder builder = _makeBuilder(holder); + unit.beginToken.offset = 10; + unit.endToken.offset = 40; + unit.accept(builder); + + CompilationUnitElement element = builder.compilationUnitElement; + _assertHasCodeRange(element, 0, 41); + } + void test_visitConstructorDeclaration_external() { ElementHolder holder = new ElementHolder(); ElementBuilder builder = _makeBuilder(holder); @@ -909,12 +931,14 @@ class C { constructorDeclaration.documentationComment = AstFactory .documentationComment( [TokenFactory.tokenFromString('/// aaa')..offset = 50], []); + constructorDeclaration.endToken.offset = 80; constructorDeclaration.accept(builder); List constructors = holder.constructors; expect(constructors, hasLength(1)); ConstructorElement constructor = constructors[0]; expect(constructor, isNotNull); + _assertHasCodeRange(constructor, 50, 31); expect(constructor.documentationComment, '/// aaa'); _assertHasDocRange(constructor, 50, 7); expect(constructor.isExternal, isFalse); @@ -993,11 +1017,14 @@ class C { AstFactory.declaredIdentifier3(variableName); AstFactory.forEachStatement( identifier, AstFactory.nullLiteral(), AstFactory.emptyStatement()); + identifier.beginToken.offset = 50; + identifier.endToken.offset = 80; identifier.accept(builder); List variables = holder.localVariables; expect(variables, hasLength(1)); LocalVariableElement variable = variables[0]; + _assertHasCodeRange(variable, 50, 31); expect(variable, isNotNull); expect(variable.hasImplicitType, isTrue); expect(variable.isConst, isFalse); @@ -1019,12 +1046,15 @@ class C { AstFactory.declaredIdentifier4(AstFactory.typeName4('E'), variableName); AstFactory.forEachStatement( identifier, AstFactory.nullLiteral(), AstFactory.emptyStatement()); + identifier.beginToken.offset = 50; + identifier.endToken.offset = 80; identifier.accept(builder); List variables = holder.localVariables; expect(variables, hasLength(1)); LocalVariableElement variable = variables[0]; expect(variable, isNotNull); + _assertHasCodeRange(variable, 50, 31); expect(variable.hasImplicitType, isFalse); expect(variable.isConst, isFalse); expect(variable.isDeprecated, isFalse); @@ -1045,11 +1075,14 @@ class C { AstFactory.positionalFormalParameter( AstFactory.simpleFormalParameter3(parameterName), AstFactory.integer(0)); + formalParameter.beginToken.offset = 50; + formalParameter.endToken.offset = 80; formalParameter.accept(builder); List parameters = holder.parameters; expect(parameters, hasLength(1)); ParameterElement parameter = parameters[0]; + _assertHasCodeRange(parameter, 50, 31); expect(parameter.hasImplicitType, isTrue); expect(parameter.initializer, isNotNull); expect(parameter.initializer.type, isNotNull); @@ -1102,11 +1135,13 @@ class C { AstFactory.enumDeclaration2(enumName, ["ONE"]); enumDeclaration.documentationComment = AstFactory.documentationComment( [TokenFactory.tokenFromString('/// aaa')..offset = 50], []); + enumDeclaration.endToken.offset = 80; enumDeclaration.accept(builder); List enums = holder.enums; expect(enums, hasLength(1)); ClassElement enumElement = enums[0]; expect(enumElement, isNotNull); + _assertHasCodeRange(enumElement, 50, 31); expect(enumElement.documentationComment, '/// aaa'); _assertHasDocRange(enumElement, 50, 7); expect(enumElement.name, enumName); @@ -1124,6 +1159,7 @@ class C { ]); fieldDeclaration.documentationComment = AstFactory.documentationComment( [TokenFactory.tokenFromString('/// aaa')..offset = 50], []); + fieldDeclaration.endToken.offset = 110; fieldDeclaration.accept(builder); List fields = holder.fields; @@ -1131,6 +1167,7 @@ class C { FieldElement firstField = fields[0]; expect(firstField, isNotNull); + _assertHasCodeRange(firstField, 50, 61); expect(firstField.documentationComment, '/// aaa'); _assertHasDocRange(firstField, 50, 7); expect(firstField.name, firstFieldName); @@ -1141,6 +1178,7 @@ class C { FieldElement secondField = fields[1]; expect(secondField, isNotNull); + _assertHasCodeRange(secondField, 50, 61); expect(secondField.documentationComment, '/// aaa'); _assertHasDocRange(secondField, 50, 7); expect(secondField.name, secondFieldName); @@ -1156,11 +1194,14 @@ class C { String parameterName = "p"; FieldFormalParameter formalParameter = AstFactory.fieldFormalParameter(null, null, parameterName); + formalParameter.beginToken.offset = 50; + formalParameter.endToken.offset = 80; formalParameter.accept(builder); List parameters = holder.parameters; expect(parameters, hasLength(1)); ParameterElement parameter = parameters[0]; expect(parameter, isNotNull); + _assertHasCodeRange(parameter, 50, 31); expect(parameter.name, parameterName); expect(parameter.initializer, isNull); expect(parameter.isConst, isFalse); @@ -1251,12 +1292,14 @@ class C { AstFactory.formalParameterList(), AstFactory.blockFunctionBody2())); declaration.documentationComment = AstFactory.documentationComment( [TokenFactory.tokenFromString('/// aaa')..offset = 50], []); + declaration.endToken.offset = 80; declaration.accept(builder); List accessors = holder.accessors; expect(accessors, hasLength(1)); PropertyAccessorElement accessor = accessors[0]; expect(accessor, isNotNull); + _assertHasCodeRange(accessor, 50, 31); expect(accessor.documentationComment, '/// aaa'); _assertHasDocRange(accessor, 50, 7); expect(accessor.name, functionName); @@ -1287,12 +1330,14 @@ class C { AstFactory.formalParameterList(), AstFactory.blockFunctionBody2())); declaration.documentationComment = AstFactory.documentationComment( [TokenFactory.tokenFromString('/// aaa')..offset = 50], []); + declaration.endToken.offset = 80; declaration.accept(builder); List functions = holder.functions; expect(functions, hasLength(1)); FunctionElement function = functions[0]; expect(function, isNotNull); + _assertHasCodeRange(function, 50, 31); expect(function.documentationComment, '/// aaa'); _assertHasDocRange(function, 50, 7); expect(function.hasImplicitReturnType, isFalse); @@ -1317,12 +1362,14 @@ class C { AstFactory.formalParameterList(), AstFactory.blockFunctionBody2())); declaration.documentationComment = AstFactory.documentationComment( [TokenFactory.tokenFromString('/// aaa')..offset = 50], []); + declaration.endToken.offset = 80; declaration.accept(builder); List accessors = holder.accessors; expect(accessors, hasLength(1)); PropertyAccessorElement accessor = accessors[0]; expect(accessor, isNotNull); + _assertHasCodeRange(accessor, 50, 31); expect(accessor.documentationComment, '/// aaa'); _assertHasDocRange(accessor, 50, 7); expect(accessor.hasImplicitReturnType, isTrue); @@ -1396,12 +1443,14 @@ class C { null, aliasName, AstFactory.typeParameterList([parameterName]), null); aliasNode.documentationComment = AstFactory.documentationComment( [TokenFactory.tokenFromString('/// aaa')..offset = 50], []); + aliasNode.endToken.offset = 80; aliasNode.accept(builder); List aliases = holder.typeAliases; expect(aliases, hasLength(1)); FunctionTypeAliasElement alias = aliases[0]; expect(alias, isNotNull); + _assertHasCodeRange(alias, 50, 31); expect(alias.documentationComment, '/// aaa'); _assertHasDocRange(alias, 50, 7); expect(alias.name, aliasName); @@ -1557,6 +1606,7 @@ class C { AstFactory.blockFunctionBody2()); methodDeclaration.documentationComment = AstFactory.documentationComment( [TokenFactory.tokenFromString('/// aaa')..offset = 50], []); + methodDeclaration.endToken.offset = 80; methodDeclaration.accept(builder); List fields = holder.fields; @@ -1568,6 +1618,7 @@ class C { expect(field.setter, isNull); PropertyAccessorElement getter = field.getter; expect(getter, isNotNull); + _assertHasCodeRange(getter, 50, 31); expect(getter.documentationComment, '/// aaa'); _assertHasDocRange(getter, 50, 7); expect(getter.hasImplicitReturnType, isTrue); @@ -1673,12 +1724,14 @@ class C { AstFactory.blockFunctionBody2()); methodDeclaration.documentationComment = AstFactory.documentationComment( [TokenFactory.tokenFromString('/// aaa')..offset = 50], []); + methodDeclaration.endToken.offset = 80; methodDeclaration.accept(builder); List methods = holder.methods; expect(methods, hasLength(1)); MethodElement method = methods[0]; expect(method, isNotNull); + _assertHasCodeRange(method, 50, 31); expect(method.documentationComment, '/// aaa'); _assertHasDocRange(method, 50, 7); expect(method.hasImplicitReturnType, isFalse); @@ -1742,6 +1795,7 @@ class C { AstFactory.blockFunctionBody2()); methodDeclaration.documentationComment = AstFactory.documentationComment( [TokenFactory.tokenFromString('/// aaa')..offset = 50], []); + methodDeclaration.endToken.offset = 80; methodDeclaration.accept(builder); List fields = holder.fields; @@ -1754,6 +1808,7 @@ class C { PropertyAccessorElement setter = field.setter; expect(setter, isNotNull); + _assertHasCodeRange(setter, 50, 31); expect(setter.documentationComment, '/// aaa'); _assertHasDocRange(setter, 50, 7); expect(setter.hasImplicitReturnType, isTrue); @@ -1983,11 +2038,14 @@ class C { AstFactory.simpleFormalParameter3(parameterName), AstFactory.identifier3("42")); _useParameterInMethod(formalParameter, 100, 110); + formalParameter.beginToken.offset = 50; + formalParameter.endToken.offset = 80; formalParameter.accept(builder); List parameters = holder.parameters; expect(parameters, hasLength(1)); ParameterElement parameter = parameters[0]; expect(parameter, isNotNull); + _assertHasCodeRange(parameter, 50, 32); expect(parameter.name, parameterName); expect(parameter.isConst, isFalse); expect(parameter.isFinal, isFalse); @@ -2088,11 +2146,14 @@ class C { AstFactory.simpleFormalParameter3(firstParameterName), AstFactory.simpleFormalParameter3(secondParameterName) ])); + typeAlias.beginToken.offset = 50; + typeAlias.endToken.offset = 80; typeAlias.accept(builder); List aliases = holder.typeAliases; expect(aliases, hasLength(1)); FunctionTypeAliasElement alias = aliases[0]; expect(alias, isNotNull); + _assertHasCodeRange(alias, 50, 31); expect(alias.name, aliasName); expect(alias.type, isNotNull); expect(alias.isSynthetic, isFalse); @@ -2139,11 +2200,13 @@ class C { ElementBuilder builder = _makeBuilder(holder); String parameterName = "E"; TypeParameter typeParameter = AstFactory.typeParameter(parameterName); + typeParameter.beginToken.offset = 50; typeParameter.accept(builder); List typeParameters = holder.typeParameters; expect(typeParameters, hasLength(1)); TypeParameterElement typeParameterElement = typeParameters[0]; expect(typeParameterElement, isNotNull); + _assertHasCodeRange(typeParameterElement, 50, 1); expect(typeParameterElement.name, parameterName); expect(typeParameterElement.bound, isNull); expect(typeParameterElement.isSynthetic, isFalse); @@ -2158,8 +2221,8 @@ class C { String variableName = "v"; VariableDeclaration variable = AstFactory.variableDeclaration2(variableName, null); - Statement statement = - AstFactory.variableDeclarationStatement2(null, [variable]); + VariableDeclarationStatement statement = + AstFactory.variableDeclarationStatement2(Keyword.VAR, [variable]); ConstructorDeclaration constructor = AstFactory.constructorDeclaration2( null, null, @@ -2168,6 +2231,8 @@ class C { AstFactory.formalParameterList(), null, AstFactory.blockFunctionBody2([statement])); + statement.beginToken.offset = 50; + statement.endToken.offset = 80; constructor.accept(builder); List constructors = holder.constructors; @@ -2176,6 +2241,7 @@ class C { constructors[0].localVariables; expect(variableElements, hasLength(1)); LocalVariableElement variableElement = variableElements[0]; + _assertHasCodeRange(variableElement, 50, 31); expect(variableElement.hasImplicitType, isTrue); expect(variableElement.name, variableName); } @@ -2354,6 +2420,12 @@ class C { expect(variable.setter, isNull); } + void _assertHasCodeRange(Element element, int offset, int length) { + ElementImpl elementImpl = element; + expect(elementImpl.codeOffset, offset); + expect(elementImpl.codeLength, length); + } + void _assertHasDocRange( Element element, int expectedOffset, int expectedLength) { // Cast to dynamic here to avoid a hint about @deprecated docRange.