@@ -436,8 +436,9 @@ class Accessor extends ModelElement implements EnclosedElement {
436436 String get sourceCode {
437437 if (_sourceCode == null ) {
438438 if (isSynthetic) {
439- _sourceCode =
440- sourceCodeFor ((element as PropertyAccessorElement ).variable);
439+ _sourceCode = packageGraph
440+ ._getModelNodeFor ((element as PropertyAccessorElement ).variable)
441+ .sourceCode;
441442 } else {
442443 _sourceCode = super .sourceCode;
443444 }
@@ -1420,13 +1421,72 @@ abstract class Categorization implements ModelElement {
14201421 }
14211422}
14221423
1424+ /// A stripped down [CommentReference] containing only that information needed
1425+ /// for Dartdoc. Drops link to the [CommentReference] after construction.
1426+ class ModelCommentReference {
1427+ final String name;
1428+ final Element staticElement;
1429+ ModelCommentReference (CommentReference ref)
1430+ : name = ref.identifier.name,
1431+ staticElement = ref.identifier.staticElement {}
1432+ }
1433+
1434+ /// Stripped down information derived from [AstNode] containing only information
1435+ /// needed for Dartdoc. Drops link to the [AstNode] after construction.
1436+ class ModelNode {
1437+ final List <ModelCommentReference > commentRefs;
1438+ final String sourceCode;
1439+ final Element element;
1440+
1441+ ModelNode (AstNode sourceNode, this .element)
1442+ : sourceCode = _sourceCodeFor (sourceNode, element),
1443+ commentRefs = _commentRefsFor (sourceNode) {}
1444+
1445+ static List <ModelCommentReference > _commentRefsFor (AstNode node) {
1446+ if (node is AnnotatedNode &&
1447+ node? .documentationComment? .references != null ) {
1448+ return node.documentationComment.references
1449+ .map ((c) => ModelCommentReference (c))
1450+ .toList (growable: false );
1451+ }
1452+ return null ;
1453+ }
1454+
1455+ static String _sourceCodeFor (AstNode node, Element element) {
1456+ String contents = getFileContentsFor (element);
1457+ if (node != null ) {
1458+ // Find the start of the line, so that we can line up all the indents.
1459+ int i = node.offset;
1460+ while (i > 0 ) {
1461+ i -= 1 ;
1462+ if (contents[i] == '\n ' || contents[i] == '\r ' ) {
1463+ i += 1 ;
1464+ break ;
1465+ }
1466+ }
1467+
1468+ // Trim the common indent from the source snippet.
1469+ var start = node.offset - (node.offset - i);
1470+ String source = contents.substring (start, node.end);
1471+
1472+ source = const HtmlEscape ().convert (source);
1473+ source = stripIndentFromSource (source);
1474+ source = stripDartdocCommentsFromSource (source);
1475+
1476+ return source.trim ();
1477+ } else {
1478+ return '' ;
1479+ }
1480+ }
1481+ }
1482+
14231483/// Classes extending this class have canonicalization support in Dartdoc.
14241484abstract class Canonicalization implements Locatable , Documentable {
14251485 bool get isCanonical;
14261486 Library get canonicalLibrary;
14271487
1428- List <CommentReference > _commentRefs;
1429- List <CommentReference > get commentRefs => _commentRefs;
1488+ List <ModelCommentReference > _commentRefs;
1489+ List <ModelCommentReference > get commentRefs => _commentRefs;
14301490
14311491 /// Pieces of the location split by [locationSplitter] (removing package: and
14321492 /// slashes).
@@ -1758,7 +1818,7 @@ class Field extends ModelElement
17581818 String get sourceCode {
17591819 if (_sourceCode == null ) {
17601820 // We could use a set to figure the dupes out, but that would lose ordering.
1761- String fieldSourceCode = sourceCodeFor (element) ?? '' ;
1821+ String fieldSourceCode = modelNode.sourceCode ?? '' ;
17621822 String getterSourceCode = getter? .sourceCode ?? '' ;
17631823 String setterSourceCode = setter? .sourceCode ?? '' ;
17641824 StringBuffer buffer = new StringBuffer ();
@@ -3036,12 +3096,10 @@ abstract class ModelElement extends Canonicalization
30363096 .packageGraph.libraryElementReexportedBy[this .element.library];
30373097 }
30383098
3039- AstNode _astNode ;
3099+ ModelNode _modelNode ;
30403100 @override
3041- AstNode get astNode {
3042- _astNode ?? = element? .computeNode ();
3043- return _astNode;
3044- }
3101+ ModelNode get modelNode =>
3102+ _modelNode ?? = packageGraph._getModelNodeFor (element);
30453103
30463104 List <String > get annotations => annotationsFromMetadata (element.metadata);
30473105
@@ -3112,7 +3170,7 @@ abstract class ModelElement extends Canonicalization
31123170 }
31133171
31143172 @override
3115- List <CommentReference > get commentRefs {
3173+ List <ModelCommentReference > get commentRefs {
31163174 if (_commentRefs == null ) {
31173175 _commentRefs = [];
31183176 for (ModelElement from in documentationFrom) {
@@ -3121,11 +3179,7 @@ abstract class ModelElement extends Canonicalization
31213179 checkReferences.add (from.enclosingCombo);
31223180 }
31233181 for (ModelElement e in checkReferences) {
3124- AstNode node = e.astNode;
3125- if (node is AnnotatedNode &&
3126- node? .documentationComment? .references != null ) {
3127- _commentRefs.addAll (node.documentationComment.references);
3128- }
3182+ _commentRefs.addAll (e.modelNode.commentRefs ?? []);
31293183 }
31303184 }
31313185 }
@@ -4674,6 +4728,16 @@ class PackageGraph {
46744728 }
46754729 }
46764730
4731+ // Many ModelElements have the same ModelNode; don't build/cache this data more
4732+ // than once for them.
4733+ final Map <Element , ModelNode > _modelNodes = Map ();
4734+ ModelNode _getModelNodeFor (element) {
4735+ /// TODO(jcollins-g): merge with removal of computeNode.
4736+ _modelNodes.putIfAbsent (
4737+ element, () => ModelNode (element? .computeNode (), element));
4738+ return _modelNodes[element];
4739+ }
4740+
46774741 SpecialClasses specialClasses;
46784742
46794743 /// It is safe to cache values derived from the _implementors table if this
@@ -6087,7 +6151,7 @@ class Parameter extends ModelElement implements EnclosedElement {
60876151}
60886152
60896153abstract class SourceCodeMixin implements Documentable {
6090- AstNode get astNode ;
6154+ ModelNode get modelNode ;
60916155
60926156 Tuple2 <int , int > get lineAndColumn;
60936157
@@ -6097,41 +6161,8 @@ abstract class SourceCodeMixin implements Documentable {
60976161
60986162 Library get library;
60996163
6100- String sourceCodeFor (Element element) {
6101- String contents = getFileContentsFor (element);
6102- var node = element.computeNode ();
6103- if (node != null ) {
6104- // Find the start of the line, so that we can line up all the indents.
6105- int i = node.offset;
6106- while (i > 0 ) {
6107- i -= 1 ;
6108- if (contents[i] == '\n ' || contents[i] == '\r ' ) {
6109- i += 1 ;
6110- break ;
6111- }
6112- }
6113-
6114- // Trim the common indent from the source snippet.
6115- var start = node.offset - (node.offset - i);
6116- String source = contents.substring (start, node.end);
6117-
6118- source = const HtmlEscape ().convert (source);
6119- source = stripIndentFromSource (source);
6120- source = stripDartdocCommentsFromSource (source);
6121-
6122- return source.trim ();
6123- } else {
6124- return '' ;
6125- }
6126- }
6127-
61286164 String _sourceCode;
6129- String get sourceCode {
6130- if (_sourceCode == null ) {
6131- _sourceCode = sourceCodeFor (element);
6132- }
6133- return _sourceCode;
6134- }
6165+ String get sourceCode => _sourceCode ?? = modelNode.sourceCode;
61356166}
61366167
61376168abstract class TypeParameters implements ModelElement {
0 commit comments