Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit a25d211

Browse files
scheglovcommit-bot@chromium.org
authored andcommitted
Detach nodes referenced by elements from original units.
This is a necessary step to keep linking elements without loading from bytes. Change-Id: I7bc8bdc0b10e178ab46d15e288a76eb3d732891f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/202160 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
1 parent 0a3b4fc commit a25d211

File tree

3 files changed

+93
-0
lines changed

3 files changed

+93
-0
lines changed

pkg/analyzer/lib/src/dart/ast/ast.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,10 @@ abstract class AstNodeImpl implements AstNode {
763763
return root;
764764
}
765765

766+
void detachFromParent() {
767+
_parent = null;
768+
}
769+
766770
@override
767771
Token? findPrevious(Token target) =>
768772
util.findPrevious(beginToken, target) ?? parent?.findPrevious(target);
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'package:analyzer/dart/ast/ast.dart';
6+
import 'package:analyzer/dart/element/element.dart';
7+
import 'package:analyzer/dart/element/visitor.dart';
8+
import 'package:analyzer/src/dart/ast/ast.dart';
9+
import 'package:analyzer/src/dart/element/element.dart';
10+
11+
/// Elements have references to AST nodes, for example initializers of constant
12+
/// variables. These nodes are attached to the whole compilation unit, and
13+
/// the whole token stream for the file. We don't want all this data after
14+
/// linking. So, we need to detach these nodes.
15+
void detachElementsFromNodes(LibraryElementImpl element) {
16+
element.accept(_Visitor());
17+
}
18+
19+
class _Visitor extends GeneralizingElementVisitor<void> {
20+
@override
21+
void visitClassElement(ClassElement element) {
22+
if (element is ClassElementImpl) {
23+
element.mixinInferenceCallback = null;
24+
}
25+
super.visitClassElement(element);
26+
}
27+
28+
@override
29+
void visitConstructorElement(ConstructorElement element) {
30+
if (element is ConstructorElementImpl) {
31+
// Make a copy, so that it is not a NodeList.
32+
var initializers = element.constantInitializers.toList();
33+
initializers.forEach(_detachNode);
34+
element.constantInitializers = initializers;
35+
}
36+
super.visitConstructorElement(element);
37+
}
38+
39+
@override
40+
void visitElement(Element element) {
41+
for (var elementAnnotation in element.metadata) {
42+
_detachNode((elementAnnotation as ElementAnnotationImpl).annotationAst);
43+
}
44+
super.visitElement(element);
45+
}
46+
47+
@override
48+
void visitParameterElement(ParameterElement element) {
49+
_detachConstVariable(element);
50+
super.visitParameterElement(element);
51+
}
52+
53+
@override
54+
void visitPropertyInducingElement(PropertyInducingElement element) {
55+
if (element is PropertyInducingElementImpl) {
56+
element.typeInference = null;
57+
}
58+
_detachConstVariable(element);
59+
}
60+
61+
void _detachConstVariable(Element element) {
62+
if (element is ConstVariableElement) {
63+
var initializer = element.constantInitializer;
64+
if (initializer is ExpressionImpl) {
65+
_detachNode(initializer);
66+
ConstantContextForExpressionImpl(initializer);
67+
}
68+
}
69+
}
70+
71+
void _detachNode(AstNode? node) {
72+
if (node is AstNodeImpl) {
73+
node.detachFromParent();
74+
// Also detach from the token stream.
75+
node.beginToken.previous = null;
76+
node.endToken.next = null;
77+
}
78+
}
79+
}

pkg/analyzer/lib/src/summary2/link.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
1313
import 'package:analyzer/src/generated/constant.dart';
1414
import 'package:analyzer/src/generated/source.dart';
1515
import 'package:analyzer/src/summary2/bundle_writer.dart';
16+
import 'package:analyzer/src/summary2/detach_nodes.dart';
1617
import 'package:analyzer/src/summary2/library_builder.dart';
1718
import 'package:analyzer/src/summary2/linked_element_factory.dart';
1819
import 'package:analyzer/src/summary2/reference.dart';
@@ -25,6 +26,8 @@ import 'package:analyzer/src/summary2/variance_builder.dart';
2526
var timerLinkingLinkingBundle = Stopwatch();
2627
var timerLinkingRemoveBundle = Stopwatch();
2728

29+
/// Note that AST units and tokens of [inputLibraries] will be damaged.
30+
///
2831
/// TODO(scheglov) deprecate `withInformative`.
2932
LinkResult link(
3033
LinkedElementFactory elementFactory,
@@ -104,6 +107,7 @@ class Linker {
104107
_resolveDefaultValues();
105108
_resolveMetadata();
106109
_collectMixinSuperInvokedNames();
110+
_detachNodes();
107111
}
108112

109113
void _collectMixinSuperInvokedNames() {
@@ -178,6 +182,12 @@ class Linker {
178182
inheritance = InheritanceManager3();
179183
}
180184

185+
void _detachNodes() {
186+
for (var builder in builders.values) {
187+
detachElementsFromNodes(builder.element);
188+
}
189+
}
190+
181191
void _performTopLevelInference() {
182192
TopLevelInference(this).infer();
183193
}

0 commit comments

Comments
 (0)