Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(18)

Unified Diff: pkg/analyzer/lib/src/dart/analysis/referenced_names.dart

Issue 2519443003: Compute names referenced in a unit. (Closed)
Patch Set: Fix for top-level declarations, more tests. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | pkg/analyzer/test/src/dart/analysis/referenced_names_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analyzer/lib/src/dart/analysis/referenced_names.dart
diff --git a/pkg/analyzer/lib/src/dart/analysis/referenced_names.dart b/pkg/analyzer/lib/src/dart/analysis/referenced_names.dart
new file mode 100644
index 0000000000000000000000000000000000000000..811aa925f59ed7771d562ec65a43b3acd6bc9bdb
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/analysis/referenced_names.dart
@@ -0,0 +1,250 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+
+/**
+ * Compute the set of external names referenced in the [unit].
+ */
+Set<String> computeReferencedNames(CompilationUnit unit) {
+ _ReferencedNamesComputer computer = new _ReferencedNamesComputer();
+ unit.accept(computer);
+ return computer.names;
+}
+
+/**
+ * Chained set of local names, that hide corresponding external names.
+ */
+class _LocalNameScope {
+ final _LocalNameScope enclosing;
+ Set<String> names;
+
+ _LocalNameScope(this.enclosing);
+
+ factory _LocalNameScope.forBlock(_LocalNameScope enclosing, Block node) {
+ _LocalNameScope scope = new _LocalNameScope(enclosing);
+ for (Statement statement in node.statements) {
+ if (statement is FunctionDeclarationStatement) {
+ scope.add(statement.functionDeclaration.name);
+ } else if (statement is VariableDeclarationStatement) {
+ scope.addVariableNames(statement.variables);
+ }
+ }
+ return scope;
+ }
+
+ factory _LocalNameScope.forClass(
+ _LocalNameScope enclosing, ClassDeclaration node) {
+ _LocalNameScope scope = new _LocalNameScope(enclosing);
+ scope.addTypeParameters(node.typeParameters);
+ for (ClassMember member in node.members) {
+ if (member is FieldDeclaration) {
+ scope.addVariableNames(member.fields);
+ } else if (member is MethodDeclaration) {
+ scope.add(member.name);
+ }
+ }
+ return scope;
+ }
+
+ factory _LocalNameScope.forClassTypeAlias(
+ _LocalNameScope enclosing, ClassTypeAlias node) {
+ _LocalNameScope scope = new _LocalNameScope(enclosing);
+ scope.addTypeParameters(node.typeParameters);
+ return scope;
+ }
+
+ factory _LocalNameScope.forFunction(
+ _LocalNameScope enclosing, FunctionDeclaration node) {
+ _LocalNameScope scope = new _LocalNameScope(enclosing);
+ scope.addTypeParameters(node.functionExpression.typeParameters);
+ scope.addFormalParameters(node.functionExpression.parameters);
+ return scope;
+ }
+
+ factory _LocalNameScope.forFunctionTypeAlias(
+ _LocalNameScope enclosing, FunctionTypeAlias node) {
+ _LocalNameScope scope = new _LocalNameScope(enclosing);
+ scope.addTypeParameters(node.typeParameters);
+ return scope;
+ }
+
+ factory _LocalNameScope.forMethod(
+ _LocalNameScope enclosing, MethodDeclaration node) {
+ _LocalNameScope scope = new _LocalNameScope(enclosing);
+ scope.addTypeParameters(node.typeParameters);
+ scope.addFormalParameters(node.parameters);
+ return scope;
+ }
+
+ factory _LocalNameScope.forUnit(CompilationUnit node) {
+ _LocalNameScope scope = new _LocalNameScope(null);
+ for (CompilationUnitMember declaration in node.declarations) {
+ if (declaration is NamedCompilationUnitMember) {
+ scope.add(declaration.name);
+ } else if (declaration is TopLevelVariableDeclaration) {
+ scope.addVariableNames(declaration.variables);
+ }
+ }
+ return scope;
+ }
+
+ void add(SimpleIdentifier identifier) {
+ if (identifier != null) {
+ names ??= new Set<String>();
+ names.add(identifier.name);
+ }
+ }
+
+ void addFormalParameters(FormalParameterList parameterList) {
+ if (parameterList != null) {
+ parameterList.parameters
+ .map((p) => p is NormalFormalParameter ? p.identifier : null)
+ .forEach(add);
+ }
+ }
+
+ void addTypeParameters(TypeParameterList typeParameterList) {
+ if (typeParameterList != null) {
+ typeParameterList.typeParameters.map((p) => p.name).forEach(add);
+ }
+ }
+
+ void addVariableNames(VariableDeclarationList variableList) {
+ for (VariableDeclaration variable in variableList.variables) {
+ add(variable.name);
+ }
+ }
+
+ bool contains(String name) {
+ if (names != null && names.contains(name)) {
+ return true;
+ }
+ if (enclosing != null) {
+ return enclosing.contains(name);
+ }
+ return false;
+ }
+}
+
+class _ReferencedNamesComputer extends GeneralizingAstVisitor {
+ final Set<String> names = new Set<String>();
+ final Set<String> importPrefixNames = new Set<String>();
+
+ _LocalNameScope localScope = new _LocalNameScope(null);
+
+ @override
+ visitBlock(Block node) {
+ _LocalNameScope outerScope = localScope;
+ try {
+ localScope = new _LocalNameScope.forBlock(localScope, node);
+ super.visitBlock(node);
+ } finally {
+ localScope = outerScope;
+ }
+ }
+
+ @override
+ visitClassDeclaration(ClassDeclaration node) {
+ _LocalNameScope outerScope = localScope;
+ try {
+ localScope = new _LocalNameScope.forClass(localScope, node);
+ super.visitClassDeclaration(node);
+ } finally {
+ localScope = outerScope;
+ }
+ }
+
+ @override
+ visitClassTypeAlias(ClassTypeAlias node) {
+ _LocalNameScope outerScope = localScope;
+ try {
+ localScope = new _LocalNameScope.forClassTypeAlias(localScope, node);
+ super.visitClassTypeAlias(node);
+ } finally {
+ localScope = outerScope;
+ }
+ }
+
+ @override
+ visitCompilationUnit(CompilationUnit node) {
+ localScope = new _LocalNameScope.forUnit(node);
+ super.visitCompilationUnit(node);
+ }
+
+ @override
+ visitConstructorName(ConstructorName node) {
+ if (node.parent is! ConstructorDeclaration) {
+ super.visitConstructorName(node);
+ }
+ }
+
+ @override
+ visitFunctionDeclaration(FunctionDeclaration node) {
+ _LocalNameScope outerScope = localScope;
+ try {
+ localScope = new _LocalNameScope.forFunction(localScope, node);
+ super.visitFunctionDeclaration(node);
+ } finally {
+ localScope = outerScope;
+ }
+ }
+
+ @override
+ visitFunctionTypeAlias(FunctionTypeAlias node) {
+ _LocalNameScope outerScope = localScope;
+ try {
+ localScope = new _LocalNameScope.forFunctionTypeAlias(localScope, node);
+ super.visitFunctionTypeAlias(node);
+ } finally {
+ localScope = outerScope;
+ }
+ }
+
+ @override
+ visitImportDirective(ImportDirective node) {
+ if (node.prefix != null) {
+ importPrefixNames.add(node.prefix.name);
+ }
+ super.visitImportDirective(node);
+ }
+
+ @override
+ visitMethodDeclaration(MethodDeclaration node) {
+ _LocalNameScope outerScope = localScope;
+ try {
+ localScope = new _LocalNameScope.forMethod(localScope, node);
+ super.visitMethodDeclaration(node);
+ } finally {
+ localScope = outerScope;
+ }
+ }
+
+ @override
+ visitSimpleIdentifier(SimpleIdentifier node) {
+ // Ignore all declarations.
+ if (node.inDeclarationContext()) {
+ return;
+ }
+ // Ignore class names references from constructors.
+ AstNode parent = node.parent;
+ if (parent is ConstructorDeclaration && parent.returnType == node) {
+ return;
+ }
+ // Prepare name.
+ String name = node.name;
+ // Ignore unqualified names shadowed by local elements.
+ if (!node.isQualified) {
+ if (localScope.contains(name)) {
+ return;
+ }
+ if (importPrefixNames.contains(name)) {
+ return;
+ }
+ }
+ // Do add the name.
+ names.add(name);
+ }
+}
« no previous file with comments | « no previous file | pkg/analyzer/test/src/dart/analysis/referenced_names_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698