mirror of
https://github.com/dart-lang/sdk
synced 2024-07-21 02:14:37 +00:00
Update some files from CRLF to LF
R=sra@google.com Review URL: https://codereview.chromium.org//1214853002.
This commit is contained in:
parent
6a69915cf5
commit
76cb9faa27
File diff suppressed because it is too large
Load diff
|
@ -1,271 +1,271 @@
|
|||
// Copyright (c) 2014, 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.
|
||||
|
||||
library analyzer2dart.semantic_visitor;
|
||||
|
||||
import 'package:analyzer/analyzer.dart';
|
||||
import 'package:analyzer/src/generated/source.dart';
|
||||
|
||||
import 'util.dart';
|
||||
import 'identifier_semantics.dart';
|
||||
|
||||
/// An AST visitor which uses the [AccessSemantics] of invocations and accesses
|
||||
/// to fine-grain visitor methods.
|
||||
abstract class SemanticVisitor<R> extends RecursiveAstVisitor<R> {
|
||||
|
||||
Source get currentSource;
|
||||
|
||||
void reportMessage(AstNode node, String message) {
|
||||
reportSourceMessage(currentSource, node, message);
|
||||
}
|
||||
|
||||
giveUp(AstNode node, String message) {
|
||||
reportMessage(node, message);
|
||||
throw new UnimplementedError(message);
|
||||
}
|
||||
|
||||
bool invariant(AstNode node, condition, String message) {
|
||||
if (condition is Function) {
|
||||
condition = condition();
|
||||
}
|
||||
if (!condition) {
|
||||
reportMessage(node, message);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
R visitDynamicInvocation(MethodInvocation node,
|
||||
AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitDynamicInvocation of $semantics');
|
||||
}
|
||||
|
||||
R visitLocalFunctionInvocation(MethodInvocation node,
|
||||
AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitLocalFunctionInvocation of $semantics');
|
||||
}
|
||||
|
||||
R visitLocalVariableInvocation(MethodInvocation node,
|
||||
AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitLocalVariableInvocation of $semantics');
|
||||
}
|
||||
|
||||
R visitParameterInvocation(MethodInvocation node,
|
||||
AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitParameterInvocation of $semantics');
|
||||
}
|
||||
|
||||
R visitStaticFieldInvocation(MethodInvocation node,
|
||||
AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitStaticFieldInvocation of $semantics');
|
||||
}
|
||||
|
||||
R visitStaticMethodInvocation(MethodInvocation node,
|
||||
AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitStaticMethodInvocation of $semantics');
|
||||
}
|
||||
|
||||
R visitStaticPropertyInvocation(MethodInvocation node,
|
||||
AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitStaticPropertyInvocation of $semantics');
|
||||
}
|
||||
|
||||
@override
|
||||
R visitMethodInvocation(MethodInvocation node) {
|
||||
if (node.target != null) {
|
||||
node.target.accept(this);
|
||||
}
|
||||
node.argumentList.accept(this);
|
||||
return handleMethodInvocation(node);
|
||||
}
|
||||
|
||||
R handleMethodInvocation(MethodInvocation node) {
|
||||
AccessSemantics semantics = node.accept(ACCESS_SEMANTICS_VISITOR);
|
||||
switch (semantics.kind) {
|
||||
case AccessKind.DYNAMIC:
|
||||
return visitDynamicInvocation(node, semantics);
|
||||
case AccessKind.LOCAL_FUNCTION:
|
||||
return visitLocalFunctionInvocation(node, semantics);
|
||||
case AccessKind.LOCAL_VARIABLE:
|
||||
return visitLocalVariableInvocation(node, semantics);
|
||||
case AccessKind.PARAMETER:
|
||||
return visitParameterInvocation(node, semantics);
|
||||
case AccessKind.STATIC_FIELD:
|
||||
return visitStaticFieldInvocation(node, semantics);
|
||||
case AccessKind.STATIC_METHOD:
|
||||
return visitStaticMethodInvocation(node, semantics);
|
||||
case AccessKind.STATIC_PROPERTY:
|
||||
return visitStaticPropertyInvocation(node, semantics);
|
||||
default:
|
||||
// Unexpected access kind.
|
||||
return giveUp(node,
|
||||
'Unexpected ${semantics} in visitMethodInvocation.');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
R visitPropertyAccess(PropertyAccess node) {
|
||||
if (node.target != null) {
|
||||
node.target.accept(this);
|
||||
}
|
||||
return handlePropertyAccess(node);
|
||||
}
|
||||
|
||||
R handlePropertyAccess(PropertyAccess node) {
|
||||
return _handlePropertyAccess(node, node.accept(ACCESS_SEMANTICS_VISITOR));
|
||||
}
|
||||
|
||||
@override
|
||||
R visitPrefixedIdentifier(PrefixedIdentifier node) {
|
||||
node.prefix.accept(this);
|
||||
return handlePrefixedIdentifier(node);
|
||||
}
|
||||
|
||||
R handlePrefixedIdentifier(PrefixedIdentifier node) {
|
||||
return _handlePropertyAccess(node, node.accept(ACCESS_SEMANTICS_VISITOR));
|
||||
}
|
||||
|
||||
@override
|
||||
R visitSimpleIdentifier(SimpleIdentifier node) {
|
||||
AccessSemantics semantics = node.accept(ACCESS_SEMANTICS_VISITOR);
|
||||
if (semantics != null) {
|
||||
return _handlePropertyAccess(node, semantics);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
R visitDynamicAccess(AstNode node, AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitDynamicAccess of $semantics');
|
||||
}
|
||||
|
||||
R visitLocalFunctionAccess(AstNode node, AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitLocalFunctionAccess of $semantics');
|
||||
}
|
||||
|
||||
R visitLocalVariableAccess(AstNode node, AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitLocalVariableAccess of $semantics');
|
||||
}
|
||||
|
||||
R visitParameterAccess(AstNode node, AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitParameterAccess of $semantics');
|
||||
}
|
||||
|
||||
R visitStaticFieldAccess(AstNode node, AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitStaticFieldAccess of $semantics');
|
||||
}
|
||||
|
||||
R visitStaticMethodAccess(AstNode node, AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitStaticMethodAccess of $semantics');
|
||||
}
|
||||
|
||||
R visitStaticPropertyAccess(AstNode node, AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitStaticPropertyAccess of $semantics');
|
||||
}
|
||||
|
||||
R visitToplevelClassAccess(AstNode node, AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitToplevelClassAccess of $semantics');
|
||||
}
|
||||
|
||||
R visitTypeParameterAccess(AstNode node, AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitTypeParameterAccess of $semantics');
|
||||
}
|
||||
|
||||
R _handlePropertyAccess(AstNode node, AccessSemantics semantics) {
|
||||
switch (semantics.kind) {
|
||||
case AccessKind.DYNAMIC:
|
||||
return visitDynamicAccess(node, semantics);
|
||||
case AccessKind.LOCAL_FUNCTION:
|
||||
return visitLocalFunctionAccess(node, semantics);
|
||||
case AccessKind.LOCAL_VARIABLE:
|
||||
return visitLocalVariableAccess(node, semantics);
|
||||
case AccessKind.PARAMETER:
|
||||
return visitParameterAccess(node, semantics);
|
||||
case AccessKind.STATIC_FIELD:
|
||||
return visitStaticFieldAccess(node, semantics);
|
||||
case AccessKind.STATIC_METHOD:
|
||||
return visitStaticMethodAccess(node, semantics);
|
||||
case AccessKind.STATIC_PROPERTY:
|
||||
return visitStaticPropertyAccess(node, semantics);
|
||||
case AccessKind.TOPLEVEL_TYPE:
|
||||
return visitToplevelClassAccess(node, semantics);
|
||||
case AccessKind.TYPE_PARAMETER:
|
||||
return visitTypeParameterAccess(node, semantics);
|
||||
default:
|
||||
// Unexpected access kind.
|
||||
return giveUp(node,
|
||||
'Unexpected ${semantics} in _handlePropertyAccess.');
|
||||
}
|
||||
}
|
||||
|
||||
R visitDynamicPropertyAssignment(AssignmentExpression node,
|
||||
AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitDynamicPropertyAssignment of $semantics');
|
||||
}
|
||||
|
||||
R visitLocalFunctionAssignment(AssignmentExpression node,
|
||||
AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitLocalFunctionAssignment of $semantics');
|
||||
}
|
||||
|
||||
R visitLocalVariableAssignment(AssignmentExpression node,
|
||||
AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitLocalVariableAssignment of $semantics');
|
||||
}
|
||||
|
||||
R visitParameterAssignment(AssignmentExpression node,
|
||||
AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitParameterAssignment of $semantics');
|
||||
}
|
||||
|
||||
R visitStaticFieldAssignment(AssignmentExpression node,
|
||||
AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitStaticFieldAssignment of $semantics');
|
||||
}
|
||||
|
||||
R visitStaticMethodAssignment(AssignmentExpression node,
|
||||
AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitStaticMethodAssignment of $semantics');
|
||||
}
|
||||
|
||||
R visitStaticPropertyAssignment(AssignmentExpression node,
|
||||
AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitStaticPropertyAssignment of $semantics');
|
||||
}
|
||||
|
||||
@override
|
||||
R visitAssignmentExpression(AssignmentExpression node) {
|
||||
super.visitAssignmentExpression(node);
|
||||
return handleAssignmentExpression(node);
|
||||
}
|
||||
|
||||
R handleAssignmentExpression(AssignmentExpression node) {
|
||||
AccessSemantics semantics =
|
||||
node.leftHandSide.accept(ACCESS_SEMANTICS_VISITOR);
|
||||
if (semantics == null) {
|
||||
return giveUp(node, 'handleAssignmentExpression with no AccessSemantics');
|
||||
} else {
|
||||
switch (semantics.kind) {
|
||||
case AccessKind.DYNAMIC:
|
||||
return visitDynamicPropertyAssignment(node, semantics);
|
||||
case AccessKind.LOCAL_FUNCTION:
|
||||
return visitLocalFunctionAssignment(node, semantics);
|
||||
case AccessKind.LOCAL_VARIABLE:
|
||||
return visitLocalVariableAssignment(node, semantics);
|
||||
case AccessKind.PARAMETER:
|
||||
return visitParameterAssignment(node, semantics);
|
||||
case AccessKind.STATIC_FIELD:
|
||||
return visitStaticFieldAssignment(node, semantics);
|
||||
case AccessKind.STATIC_METHOD:
|
||||
return visitStaticMethodAssignment(node, semantics);
|
||||
case AccessKind.STATIC_PROPERTY:
|
||||
return visitStaticPropertyAssignment(node, semantics);
|
||||
default:
|
||||
// Unexpected access kind.
|
||||
return giveUp(node,
|
||||
'Unexpected ${semantics} in _handlePropertyAccess.');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Copyright (c) 2014, 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.
|
||||
|
||||
library analyzer2dart.semantic_visitor;
|
||||
|
||||
import 'package:analyzer/analyzer.dart';
|
||||
import 'package:analyzer/src/generated/source.dart';
|
||||
|
||||
import 'util.dart';
|
||||
import 'identifier_semantics.dart';
|
||||
|
||||
/// An AST visitor which uses the [AccessSemantics] of invocations and accesses
|
||||
/// to fine-grain visitor methods.
|
||||
abstract class SemanticVisitor<R> extends RecursiveAstVisitor<R> {
|
||||
|
||||
Source get currentSource;
|
||||
|
||||
void reportMessage(AstNode node, String message) {
|
||||
reportSourceMessage(currentSource, node, message);
|
||||
}
|
||||
|
||||
giveUp(AstNode node, String message) {
|
||||
reportMessage(node, message);
|
||||
throw new UnimplementedError(message);
|
||||
}
|
||||
|
||||
bool invariant(AstNode node, condition, String message) {
|
||||
if (condition is Function) {
|
||||
condition = condition();
|
||||
}
|
||||
if (!condition) {
|
||||
reportMessage(node, message);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
R visitDynamicInvocation(MethodInvocation node,
|
||||
AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitDynamicInvocation of $semantics');
|
||||
}
|
||||
|
||||
R visitLocalFunctionInvocation(MethodInvocation node,
|
||||
AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitLocalFunctionInvocation of $semantics');
|
||||
}
|
||||
|
||||
R visitLocalVariableInvocation(MethodInvocation node,
|
||||
AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitLocalVariableInvocation of $semantics');
|
||||
}
|
||||
|
||||
R visitParameterInvocation(MethodInvocation node,
|
||||
AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitParameterInvocation of $semantics');
|
||||
}
|
||||
|
||||
R visitStaticFieldInvocation(MethodInvocation node,
|
||||
AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitStaticFieldInvocation of $semantics');
|
||||
}
|
||||
|
||||
R visitStaticMethodInvocation(MethodInvocation node,
|
||||
AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitStaticMethodInvocation of $semantics');
|
||||
}
|
||||
|
||||
R visitStaticPropertyInvocation(MethodInvocation node,
|
||||
AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitStaticPropertyInvocation of $semantics');
|
||||
}
|
||||
|
||||
@override
|
||||
R visitMethodInvocation(MethodInvocation node) {
|
||||
if (node.target != null) {
|
||||
node.target.accept(this);
|
||||
}
|
||||
node.argumentList.accept(this);
|
||||
return handleMethodInvocation(node);
|
||||
}
|
||||
|
||||
R handleMethodInvocation(MethodInvocation node) {
|
||||
AccessSemantics semantics = node.accept(ACCESS_SEMANTICS_VISITOR);
|
||||
switch (semantics.kind) {
|
||||
case AccessKind.DYNAMIC:
|
||||
return visitDynamicInvocation(node, semantics);
|
||||
case AccessKind.LOCAL_FUNCTION:
|
||||
return visitLocalFunctionInvocation(node, semantics);
|
||||
case AccessKind.LOCAL_VARIABLE:
|
||||
return visitLocalVariableInvocation(node, semantics);
|
||||
case AccessKind.PARAMETER:
|
||||
return visitParameterInvocation(node, semantics);
|
||||
case AccessKind.STATIC_FIELD:
|
||||
return visitStaticFieldInvocation(node, semantics);
|
||||
case AccessKind.STATIC_METHOD:
|
||||
return visitStaticMethodInvocation(node, semantics);
|
||||
case AccessKind.STATIC_PROPERTY:
|
||||
return visitStaticPropertyInvocation(node, semantics);
|
||||
default:
|
||||
// Unexpected access kind.
|
||||
return giveUp(node,
|
||||
'Unexpected ${semantics} in visitMethodInvocation.');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
R visitPropertyAccess(PropertyAccess node) {
|
||||
if (node.target != null) {
|
||||
node.target.accept(this);
|
||||
}
|
||||
return handlePropertyAccess(node);
|
||||
}
|
||||
|
||||
R handlePropertyAccess(PropertyAccess node) {
|
||||
return _handlePropertyAccess(node, node.accept(ACCESS_SEMANTICS_VISITOR));
|
||||
}
|
||||
|
||||
@override
|
||||
R visitPrefixedIdentifier(PrefixedIdentifier node) {
|
||||
node.prefix.accept(this);
|
||||
return handlePrefixedIdentifier(node);
|
||||
}
|
||||
|
||||
R handlePrefixedIdentifier(PrefixedIdentifier node) {
|
||||
return _handlePropertyAccess(node, node.accept(ACCESS_SEMANTICS_VISITOR));
|
||||
}
|
||||
|
||||
@override
|
||||
R visitSimpleIdentifier(SimpleIdentifier node) {
|
||||
AccessSemantics semantics = node.accept(ACCESS_SEMANTICS_VISITOR);
|
||||
if (semantics != null) {
|
||||
return _handlePropertyAccess(node, semantics);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
R visitDynamicAccess(AstNode node, AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitDynamicAccess of $semantics');
|
||||
}
|
||||
|
||||
R visitLocalFunctionAccess(AstNode node, AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitLocalFunctionAccess of $semantics');
|
||||
}
|
||||
|
||||
R visitLocalVariableAccess(AstNode node, AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitLocalVariableAccess of $semantics');
|
||||
}
|
||||
|
||||
R visitParameterAccess(AstNode node, AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitParameterAccess of $semantics');
|
||||
}
|
||||
|
||||
R visitStaticFieldAccess(AstNode node, AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitStaticFieldAccess of $semantics');
|
||||
}
|
||||
|
||||
R visitStaticMethodAccess(AstNode node, AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitStaticMethodAccess of $semantics');
|
||||
}
|
||||
|
||||
R visitStaticPropertyAccess(AstNode node, AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitStaticPropertyAccess of $semantics');
|
||||
}
|
||||
|
||||
R visitToplevelClassAccess(AstNode node, AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitToplevelClassAccess of $semantics');
|
||||
}
|
||||
|
||||
R visitTypeParameterAccess(AstNode node, AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitTypeParameterAccess of $semantics');
|
||||
}
|
||||
|
||||
R _handlePropertyAccess(AstNode node, AccessSemantics semantics) {
|
||||
switch (semantics.kind) {
|
||||
case AccessKind.DYNAMIC:
|
||||
return visitDynamicAccess(node, semantics);
|
||||
case AccessKind.LOCAL_FUNCTION:
|
||||
return visitLocalFunctionAccess(node, semantics);
|
||||
case AccessKind.LOCAL_VARIABLE:
|
||||
return visitLocalVariableAccess(node, semantics);
|
||||
case AccessKind.PARAMETER:
|
||||
return visitParameterAccess(node, semantics);
|
||||
case AccessKind.STATIC_FIELD:
|
||||
return visitStaticFieldAccess(node, semantics);
|
||||
case AccessKind.STATIC_METHOD:
|
||||
return visitStaticMethodAccess(node, semantics);
|
||||
case AccessKind.STATIC_PROPERTY:
|
||||
return visitStaticPropertyAccess(node, semantics);
|
||||
case AccessKind.TOPLEVEL_TYPE:
|
||||
return visitToplevelClassAccess(node, semantics);
|
||||
case AccessKind.TYPE_PARAMETER:
|
||||
return visitTypeParameterAccess(node, semantics);
|
||||
default:
|
||||
// Unexpected access kind.
|
||||
return giveUp(node,
|
||||
'Unexpected ${semantics} in _handlePropertyAccess.');
|
||||
}
|
||||
}
|
||||
|
||||
R visitDynamicPropertyAssignment(AssignmentExpression node,
|
||||
AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitDynamicPropertyAssignment of $semantics');
|
||||
}
|
||||
|
||||
R visitLocalFunctionAssignment(AssignmentExpression node,
|
||||
AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitLocalFunctionAssignment of $semantics');
|
||||
}
|
||||
|
||||
R visitLocalVariableAssignment(AssignmentExpression node,
|
||||
AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitLocalVariableAssignment of $semantics');
|
||||
}
|
||||
|
||||
R visitParameterAssignment(AssignmentExpression node,
|
||||
AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitParameterAssignment of $semantics');
|
||||
}
|
||||
|
||||
R visitStaticFieldAssignment(AssignmentExpression node,
|
||||
AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitStaticFieldAssignment of $semantics');
|
||||
}
|
||||
|
||||
R visitStaticMethodAssignment(AssignmentExpression node,
|
||||
AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitStaticMethodAssignment of $semantics');
|
||||
}
|
||||
|
||||
R visitStaticPropertyAssignment(AssignmentExpression node,
|
||||
AccessSemantics semantics) {
|
||||
return giveUp(node, 'visitStaticPropertyAssignment of $semantics');
|
||||
}
|
||||
|
||||
@override
|
||||
R visitAssignmentExpression(AssignmentExpression node) {
|
||||
super.visitAssignmentExpression(node);
|
||||
return handleAssignmentExpression(node);
|
||||
}
|
||||
|
||||
R handleAssignmentExpression(AssignmentExpression node) {
|
||||
AccessSemantics semantics =
|
||||
node.leftHandSide.accept(ACCESS_SEMANTICS_VISITOR);
|
||||
if (semantics == null) {
|
||||
return giveUp(node, 'handleAssignmentExpression with no AccessSemantics');
|
||||
} else {
|
||||
switch (semantics.kind) {
|
||||
case AccessKind.DYNAMIC:
|
||||
return visitDynamicPropertyAssignment(node, semantics);
|
||||
case AccessKind.LOCAL_FUNCTION:
|
||||
return visitLocalFunctionAssignment(node, semantics);
|
||||
case AccessKind.LOCAL_VARIABLE:
|
||||
return visitLocalVariableAssignment(node, semantics);
|
||||
case AccessKind.PARAMETER:
|
||||
return visitParameterAssignment(node, semantics);
|
||||
case AccessKind.STATIC_FIELD:
|
||||
return visitStaticFieldAssignment(node, semantics);
|
||||
case AccessKind.STATIC_METHOD:
|
||||
return visitStaticMethodAssignment(node, semantics);
|
||||
case AccessKind.STATIC_PROPERTY:
|
||||
return visitStaticPropertyAssignment(node, semantics);
|
||||
default:
|
||||
// Unexpected access kind.
|
||||
return giveUp(node,
|
||||
'Unexpected ${semantics} in _handlePropertyAccess.');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,42 +1,42 @@
|
|||
// Copyright (c) 2014, 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.
|
||||
|
||||
// Utility function shared between different parts of analyzer2dart.
|
||||
|
||||
library analyzer2dart.util;
|
||||
|
||||
import 'package:analyzer/analyzer.dart';
|
||||
import 'package:analyzer/src/generated/source.dart';
|
||||
import 'package:compiler/src/elements/elements.dart' show PublicName;
|
||||
import 'package:compiler/src/universe/universe.dart';
|
||||
import 'package:compiler/src/io/source_file.dart';
|
||||
|
||||
CallStructure createCallStructureFromMethodInvocation(ArgumentList node) {
|
||||
int arity = 0;
|
||||
List<String> namedArguments = <String>[];
|
||||
for (Expression argument in node.arguments) {
|
||||
if (argument is NamedExpression) {
|
||||
namedArguments.add(argument.name.label.name);
|
||||
} else {
|
||||
arity++;
|
||||
}
|
||||
}
|
||||
return new CallStructure(arity, namedArguments);
|
||||
}
|
||||
|
||||
Selector createSelectorFromMethodInvocation(ArgumentList node,
|
||||
String name) {
|
||||
CallStructure callStructure = createCallStructureFromMethodInvocation(node);
|
||||
// TODO(johnniwinther): Support private names.
|
||||
return new Selector(SelectorKind.CALL, new PublicName(name), callStructure);
|
||||
}
|
||||
|
||||
/// Prints [message] together with source code pointed to by [node] from
|
||||
/// [source].
|
||||
void reportSourceMessage(Source source, AstNode node, String message) {
|
||||
SourceFile sourceFile =
|
||||
new StringSourceFile.fromName(source.fullName, source.contents.data);
|
||||
|
||||
print(sourceFile.getLocationMessage(message, node.offset, node.end));
|
||||
}
|
||||
// Copyright (c) 2014, 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.
|
||||
|
||||
// Utility function shared between different parts of analyzer2dart.
|
||||
|
||||
library analyzer2dart.util;
|
||||
|
||||
import 'package:analyzer/analyzer.dart';
|
||||
import 'package:analyzer/src/generated/source.dart';
|
||||
import 'package:compiler/src/elements/elements.dart' show PublicName;
|
||||
import 'package:compiler/src/universe/universe.dart';
|
||||
import 'package:compiler/src/io/source_file.dart';
|
||||
|
||||
CallStructure createCallStructureFromMethodInvocation(ArgumentList node) {
|
||||
int arity = 0;
|
||||
List<String> namedArguments = <String>[];
|
||||
for (Expression argument in node.arguments) {
|
||||
if (argument is NamedExpression) {
|
||||
namedArguments.add(argument.name.label.name);
|
||||
} else {
|
||||
arity++;
|
||||
}
|
||||
}
|
||||
return new CallStructure(arity, namedArguments);
|
||||
}
|
||||
|
||||
Selector createSelectorFromMethodInvocation(ArgumentList node,
|
||||
String name) {
|
||||
CallStructure callStructure = createCallStructureFromMethodInvocation(node);
|
||||
// TODO(johnniwinther): Support private names.
|
||||
return new Selector(SelectorKind.CALL, new PublicName(name), callStructure);
|
||||
}
|
||||
|
||||
/// Prints [message] together with source code pointed to by [node] from
|
||||
/// [source].
|
||||
void reportSourceMessage(Source source, AstNode node, String message) {
|
||||
SourceFile sourceFile =
|
||||
new StringSourceFile.fromName(source.fullName, source.contents.data);
|
||||
|
||||
print(sourceFile.getLocationMessage(message, node.offset, node.end));
|
||||
}
|
||||
|
|
|
@ -1,472 +1,472 @@
|
|||
// Copyright (c) 2015, 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.
|
||||
|
||||
/// Mixins that implement convenience methods on [Element] subclasses.
|
||||
|
||||
library elements.common;
|
||||
|
||||
import '../dart2jslib.dart' show Compiler, isPrivateName;
|
||||
import '../dart_types.dart' show DartType, InterfaceType, FunctionType;
|
||||
import '../util/util.dart' show Link;
|
||||
|
||||
import 'elements.dart';
|
||||
|
||||
abstract class ElementCommon implements Element {
|
||||
@override
|
||||
bool get isLibrary => kind == ElementKind.LIBRARY;
|
||||
|
||||
@override
|
||||
bool get isCompilationUnit => kind == ElementKind.COMPILATION_UNIT;
|
||||
|
||||
@override
|
||||
bool get isPrefix => kind == ElementKind.PREFIX;
|
||||
|
||||
@override
|
||||
bool get isClass => kind == ElementKind.CLASS;
|
||||
|
||||
@override
|
||||
bool get isTypeVariable => kind == ElementKind.TYPE_VARIABLE;
|
||||
|
||||
@override
|
||||
bool get isTypedef => kind == ElementKind.TYPEDEF;
|
||||
|
||||
@override
|
||||
bool get isFunction => kind == ElementKind.FUNCTION;
|
||||
|
||||
@override
|
||||
bool get isAccessor => isGetter || isSetter;
|
||||
|
||||
@override
|
||||
bool get isGetter => kind == ElementKind.GETTER;
|
||||
|
||||
@override
|
||||
bool get isSetter => kind == ElementKind.SETTER;
|
||||
|
||||
@override
|
||||
bool get isConstructor => isGenerativeConstructor || isFactoryConstructor;
|
||||
|
||||
@override
|
||||
bool get isGenerativeConstructor =>
|
||||
kind == ElementKind.GENERATIVE_CONSTRUCTOR;
|
||||
|
||||
@override
|
||||
bool get isGenerativeConstructorBody =>
|
||||
kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY;
|
||||
|
||||
@override
|
||||
bool get isVariable => kind == ElementKind.VARIABLE;
|
||||
|
||||
@override
|
||||
bool get isField => kind == ElementKind.FIELD;
|
||||
|
||||
@override
|
||||
bool get isAbstractField => kind == ElementKind.ABSTRACT_FIELD;
|
||||
|
||||
@override
|
||||
bool get isParameter => kind == ElementKind.PARAMETER;
|
||||
|
||||
@override
|
||||
bool get isInitializingFormal => kind == ElementKind.INITIALIZING_FORMAL;
|
||||
|
||||
@override
|
||||
bool get isErroneous => kind == ElementKind.ERROR;
|
||||
|
||||
@override
|
||||
bool get isAmbiguous => kind == ElementKind.AMBIGUOUS;
|
||||
|
||||
@override
|
||||
bool get isWarnOnUse => kind == ElementKind.WARN_ON_USE;
|
||||
|
||||
@override
|
||||
bool get impliesType => (kind.category & ElementCategory.IMPLIES_TYPE) != 0;
|
||||
|
||||
@override
|
||||
Element get declaration => this;
|
||||
|
||||
@override
|
||||
Element get implementation => this;
|
||||
|
||||
@override
|
||||
bool get isDeclaration => true;
|
||||
|
||||
@override
|
||||
bool get isPatched => false;
|
||||
|
||||
@override
|
||||
bool get isPatch => false;
|
||||
|
||||
@override
|
||||
bool get isImplementation => true;
|
||||
|
||||
@override
|
||||
bool get isInjected => !isPatch && implementationLibrary.isPatch;
|
||||
|
||||
@override
|
||||
Element get patch {
|
||||
throw new UnsupportedError('patch is not supported on $this');
|
||||
}
|
||||
|
||||
@override
|
||||
Element get origin {
|
||||
throw new UnsupportedError('origin is not supported on $this');
|
||||
}
|
||||
}
|
||||
|
||||
abstract class LibraryElementCommon implements LibraryElement {
|
||||
@override
|
||||
bool get isDartCore => canonicalUri == Compiler.DART_CORE;
|
||||
|
||||
@override
|
||||
bool get isPlatformLibrary => canonicalUri.scheme == 'dart';
|
||||
|
||||
@override
|
||||
bool get isPackageLibrary => canonicalUri.scheme == 'package';
|
||||
|
||||
@override
|
||||
bool get isInternalLibrary =>
|
||||
isPlatformLibrary && canonicalUri.path.startsWith('_');
|
||||
}
|
||||
|
||||
abstract class ClassElementCommon implements ClassElement {
|
||||
|
||||
@override
|
||||
Link<DartType> get allSupertypes => allSupertypesAndSelf.supertypes;
|
||||
|
||||
@override
|
||||
int get hierarchyDepth => allSupertypesAndSelf.maxDepth;
|
||||
|
||||
@override
|
||||
InterfaceType asInstanceOf(ClassElement cls) {
|
||||
if (cls == this) return thisType;
|
||||
return allSupertypesAndSelf.asInstanceOf(cls);
|
||||
}
|
||||
|
||||
@override
|
||||
ConstructorElement lookupConstructor(String name) {
|
||||
Element result = localLookup(name);
|
||||
return result != null && result.isConstructor ? result : null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find the first member in the class chain with the given [memberName].
|
||||
*
|
||||
* This method is NOT to be used for resolving
|
||||
* unqualified sends because it does not implement the scoping
|
||||
* rules, where library scope comes before superclass scope.
|
||||
*
|
||||
* When called on the implementation element both members declared in the
|
||||
* origin and the patch class are returned.
|
||||
*/
|
||||
Element lookupByName(Name memberName) {
|
||||
return internalLookupByName(memberName, isSuperLookup: false);
|
||||
}
|
||||
|
||||
Element lookupSuperByName(Name memberName) {
|
||||
return internalLookupByName(memberName, isSuperLookup: true);
|
||||
}
|
||||
|
||||
Element internalLookupByName(Name memberName, {bool isSuperLookup}) {
|
||||
String name = memberName.text;
|
||||
bool isPrivate = memberName.isPrivate;
|
||||
LibraryElement library = memberName.library;
|
||||
for (ClassElement current = isSuperLookup ? superclass : this;
|
||||
current != null;
|
||||
current = current.superclass) {
|
||||
Element member = current.lookupLocalMember(name);
|
||||
if (member == null && current.isPatched) {
|
||||
// Doing lookups on selectors is done after resolution, so it
|
||||
// is safe to look in the patch class.
|
||||
member = current.patch.lookupLocalMember(name);
|
||||
}
|
||||
if (member == null) continue;
|
||||
// Private members from a different library are not visible.
|
||||
if (isPrivate && !identical(library, member.library)) continue;
|
||||
// Static members are not inherited.
|
||||
if (member.isStatic && !identical(this, current)) continue;
|
||||
// If we find an abstract field we have to make sure that it has
|
||||
// the getter or setter part we're actually looking
|
||||
// for. Otherwise, we continue up the superclass chain.
|
||||
if (member.isAbstractField) {
|
||||
AbstractFieldElement field = member;
|
||||
FunctionElement getter = field.getter;
|
||||
FunctionElement setter = field.setter;
|
||||
if (memberName.isSetter) {
|
||||
// Abstract members can be defined in a super class.
|
||||
if (setter != null && !setter.isAbstract) {
|
||||
return setter;
|
||||
}
|
||||
} else {
|
||||
if (getter != null && !getter.isAbstract) {
|
||||
return getter;
|
||||
}
|
||||
}
|
||||
// Abstract members can be defined in a super class.
|
||||
} else if (!member.isAbstract) {
|
||||
return member;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the first member in the class chain with the given
|
||||
* [memberName]. This method is NOT to be used for resolving
|
||||
* unqualified sends because it does not implement the scoping
|
||||
* rules, where library scope comes before superclass scope.
|
||||
*/
|
||||
@override
|
||||
Element lookupMember(String memberName) {
|
||||
Element localMember = lookupLocalMember(memberName);
|
||||
return localMember == null ? lookupSuperMember(memberName) : localMember;
|
||||
}
|
||||
|
||||
@override
|
||||
Link<Element> get constructors {
|
||||
// TODO(ajohnsen): See if we can avoid this method at some point.
|
||||
Link<Element> result = const Link<Element>();
|
||||
// TODO(johnniwinther): Should we include injected constructors?
|
||||
forEachMember((_, Element member) {
|
||||
if (member.isConstructor) result = result.prepend(member);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup super members for the class. This will ignore constructors.
|
||||
*/
|
||||
@override
|
||||
Element lookupSuperMember(String memberName) {
|
||||
return lookupSuperMemberInLibrary(memberName, library);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup super members for the class that is accessible in [library].
|
||||
* This will ignore constructors.
|
||||
*/
|
||||
@override
|
||||
Element lookupSuperMemberInLibrary(String memberName,
|
||||
LibraryElement library) {
|
||||
bool isPrivate = isPrivateName(memberName);
|
||||
for (ClassElement s = superclass; s != null; s = s.superclass) {
|
||||
// Private members from a different library are not visible.
|
||||
if (isPrivate && !identical(library, s.library)) continue;
|
||||
Element e = s.lookupLocalMember(memberName);
|
||||
if (e == null) continue;
|
||||
// Static members are not inherited.
|
||||
if (e.isStatic) continue;
|
||||
return e;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup local members in the class. This will ignore constructors.
|
||||
*/
|
||||
@override
|
||||
Element lookupLocalMember(String memberName) {
|
||||
var result = localLookup(memberName);
|
||||
if (result != null && result.isConstructor) return null;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs through all members of this class.
|
||||
*
|
||||
* The enclosing class is passed to the callback. This is useful when
|
||||
* [includeSuperAndInjectedMembers] is [:true:].
|
||||
*
|
||||
* When called on an implementation element both the members in the origin
|
||||
* and patch class are included.
|
||||
*/
|
||||
// TODO(johnniwinther): Clean up lookup to get rid of the include predicates.
|
||||
@override
|
||||
void forEachMember(void f(ClassElement enclosingClass, Element member),
|
||||
{includeBackendMembers: false,
|
||||
includeSuperAndInjectedMembers: false}) {
|
||||
bool includeInjectedMembers = includeSuperAndInjectedMembers || isPatch;
|
||||
ClassElement classElement = declaration;
|
||||
do {
|
||||
// Iterate through the members in textual order, which requires
|
||||
// to reverse the data structure [localMembers] we created.
|
||||
// Textual order may be important for certain operations, for
|
||||
// example when emitting the initializers of fields.
|
||||
classElement.forEachLocalMember((e) => f(classElement, e));
|
||||
if (includeBackendMembers) {
|
||||
classElement.forEachBackendMember((e) => f(classElement, e));
|
||||
}
|
||||
if (includeInjectedMembers) {
|
||||
if (classElement.patch != null) {
|
||||
classElement.patch.forEachLocalMember((e) {
|
||||
if (!e.isPatch) f(classElement, e);
|
||||
});
|
||||
}
|
||||
}
|
||||
classElement = includeSuperAndInjectedMembers
|
||||
? classElement.superclass
|
||||
: null;
|
||||
} while (classElement != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs through all instance-field members of this class.
|
||||
*
|
||||
* The enclosing class is passed to the callback. This is useful when
|
||||
* [includeSuperAndInjectedMembers] is [:true:].
|
||||
*
|
||||
* When called on the implementation element both the fields declared in the
|
||||
* origin and in the patch are included.
|
||||
*/
|
||||
@override
|
||||
void forEachInstanceField(void f(ClassElement enclosingClass,
|
||||
FieldElement field),
|
||||
{bool includeSuperAndInjectedMembers: false}) {
|
||||
// Filters so that [f] is only invoked with instance fields.
|
||||
void fieldFilter(ClassElement enclosingClass, Element member) {
|
||||
if (member.isInstanceMember && member.kind == ElementKind.FIELD) {
|
||||
f(enclosingClass, member);
|
||||
}
|
||||
}
|
||||
|
||||
forEachMember(fieldFilter,
|
||||
includeSuperAndInjectedMembers: includeSuperAndInjectedMembers);
|
||||
}
|
||||
|
||||
/// Similar to [forEachInstanceField] but visits static fields.
|
||||
@override
|
||||
void forEachStaticField(void f(ClassElement enclosingClass, Element field)) {
|
||||
// Filters so that [f] is only invoked with static fields.
|
||||
void fieldFilter(ClassElement enclosingClass, Element member) {
|
||||
if (!member.isInstanceMember && member.kind == ElementKind.FIELD) {
|
||||
f(enclosingClass, member);
|
||||
}
|
||||
}
|
||||
|
||||
forEachMember(fieldFilter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the [fieldMember] shadows another field. The given
|
||||
* [fieldMember] must be a member of this class, i.e. if there is a field of
|
||||
* the same name in the superclass chain.
|
||||
*
|
||||
* This method also works if the [fieldMember] is private.
|
||||
*/
|
||||
@override
|
||||
bool hasFieldShadowedBy(Element fieldMember) {
|
||||
assert(fieldMember.isField);
|
||||
String fieldName = fieldMember.name;
|
||||
bool isPrivate = isPrivateName(fieldName);
|
||||
LibraryElement memberLibrary = fieldMember.library;
|
||||
ClassElement lookupClass = this.superclass;
|
||||
while (lookupClass != null) {
|
||||
Element foundMember = lookupClass.lookupLocalMember(fieldName);
|
||||
if (foundMember != null) {
|
||||
if (foundMember.isField) {
|
||||
if (!isPrivate || memberLibrary == foundMember.library) {
|
||||
// Private fields can only be shadowed by a field declared in the
|
||||
// same library.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
lookupClass = lookupClass.superclass;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
bool implementsInterface(ClassElement intrface) {
|
||||
for (DartType implementedInterfaceType in allSupertypes) {
|
||||
ClassElement implementedInterface = implementedInterfaceType.element;
|
||||
if (identical(implementedInterface, intrface)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if [this] is a subclass of [cls].
|
||||
*
|
||||
* This method is not to be used for checking type hierarchy and
|
||||
* assignments, because it does not take parameterized types into
|
||||
* account.
|
||||
*/
|
||||
bool isSubclassOf(ClassElement cls) {
|
||||
// Use [declaration] for both [this] and [cls], because
|
||||
// declaration classes hold the superclass hierarchy.
|
||||
cls = cls.declaration;
|
||||
for (ClassElement s = declaration; s != null; s = s.superclass) {
|
||||
if (identical(s, cls)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
FunctionType get callType {
|
||||
MemberSignature member =
|
||||
lookupInterfaceMember(const PublicName(Compiler.CALL_OPERATOR_NAME));
|
||||
return member != null && member.isMethod ? member.type : null;
|
||||
}
|
||||
}
|
||||
|
||||
abstract class FunctionSignatureCommon implements FunctionSignature {
|
||||
void forEachRequiredParameter(void function(Element parameter)) {
|
||||
requiredParameters.forEach(function);
|
||||
}
|
||||
|
||||
void forEachOptionalParameter(void function(Element parameter)) {
|
||||
optionalParameters.forEach(function);
|
||||
}
|
||||
|
||||
Element get firstOptionalParameter => optionalParameters.first;
|
||||
|
||||
void forEachParameter(void function(Element parameter)) {
|
||||
forEachRequiredParameter(function);
|
||||
forEachOptionalParameter(function);
|
||||
}
|
||||
|
||||
void orderedForEachParameter(void function(Element parameter)) {
|
||||
forEachRequiredParameter(function);
|
||||
orderedOptionalParameters.forEach(function);
|
||||
}
|
||||
|
||||
int get parameterCount => requiredParameterCount + optionalParameterCount;
|
||||
|
||||
/**
|
||||
* Check whether a function with this signature can be used instead of a
|
||||
* function with signature [signature] without causing a `noSuchMethod`
|
||||
* exception/call.
|
||||
*/
|
||||
bool isCompatibleWith(FunctionSignature signature) {
|
||||
if (optionalParametersAreNamed) {
|
||||
if (!signature.optionalParametersAreNamed) {
|
||||
return requiredParameterCount == signature.parameterCount;
|
||||
}
|
||||
// If both signatures have named parameters, then they must have
|
||||
// the same number of required parameters, and the names in
|
||||
// [signature] must all be in [:this:].
|
||||
if (requiredParameterCount != signature.requiredParameterCount) {
|
||||
return false;
|
||||
}
|
||||
Set<String> names = optionalParameters.map(
|
||||
(Element element) => element.name).toSet();
|
||||
for (Element namedParameter in signature.optionalParameters) {
|
||||
if (!names.contains(namedParameter.name)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (signature.optionalParametersAreNamed) return false;
|
||||
// There must be at least as many arguments as in the other signature, but
|
||||
// this signature must not have more required parameters. Having more
|
||||
// optional parameters is not a problem, they simply are never provided
|
||||
// by call sites of a call to a method with the other signature.
|
||||
int otherTotalCount = signature.parameterCount;
|
||||
return requiredParameterCount <= otherTotalCount
|
||||
&& parameterCount >= otherTotalCount;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// Copyright (c) 2015, 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.
|
||||
|
||||
/// Mixins that implement convenience methods on [Element] subclasses.
|
||||
|
||||
library elements.common;
|
||||
|
||||
import '../dart2jslib.dart' show Compiler, isPrivateName;
|
||||
import '../dart_types.dart' show DartType, InterfaceType, FunctionType;
|
||||
import '../util/util.dart' show Link;
|
||||
|
||||
import 'elements.dart';
|
||||
|
||||
abstract class ElementCommon implements Element {
|
||||
@override
|
||||
bool get isLibrary => kind == ElementKind.LIBRARY;
|
||||
|
||||
@override
|
||||
bool get isCompilationUnit => kind == ElementKind.COMPILATION_UNIT;
|
||||
|
||||
@override
|
||||
bool get isPrefix => kind == ElementKind.PREFIX;
|
||||
|
||||
@override
|
||||
bool get isClass => kind == ElementKind.CLASS;
|
||||
|
||||
@override
|
||||
bool get isTypeVariable => kind == ElementKind.TYPE_VARIABLE;
|
||||
|
||||
@override
|
||||
bool get isTypedef => kind == ElementKind.TYPEDEF;
|
||||
|
||||
@override
|
||||
bool get isFunction => kind == ElementKind.FUNCTION;
|
||||
|
||||
@override
|
||||
bool get isAccessor => isGetter || isSetter;
|
||||
|
||||
@override
|
||||
bool get isGetter => kind == ElementKind.GETTER;
|
||||
|
||||
@override
|
||||
bool get isSetter => kind == ElementKind.SETTER;
|
||||
|
||||
@override
|
||||
bool get isConstructor => isGenerativeConstructor || isFactoryConstructor;
|
||||
|
||||
@override
|
||||
bool get isGenerativeConstructor =>
|
||||
kind == ElementKind.GENERATIVE_CONSTRUCTOR;
|
||||
|
||||
@override
|
||||
bool get isGenerativeConstructorBody =>
|
||||
kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY;
|
||||
|
||||
@override
|
||||
bool get isVariable => kind == ElementKind.VARIABLE;
|
||||
|
||||
@override
|
||||
bool get isField => kind == ElementKind.FIELD;
|
||||
|
||||
@override
|
||||
bool get isAbstractField => kind == ElementKind.ABSTRACT_FIELD;
|
||||
|
||||
@override
|
||||
bool get isParameter => kind == ElementKind.PARAMETER;
|
||||
|
||||
@override
|
||||
bool get isInitializingFormal => kind == ElementKind.INITIALIZING_FORMAL;
|
||||
|
||||
@override
|
||||
bool get isErroneous => kind == ElementKind.ERROR;
|
||||
|
||||
@override
|
||||
bool get isAmbiguous => kind == ElementKind.AMBIGUOUS;
|
||||
|
||||
@override
|
||||
bool get isWarnOnUse => kind == ElementKind.WARN_ON_USE;
|
||||
|
||||
@override
|
||||
bool get impliesType => (kind.category & ElementCategory.IMPLIES_TYPE) != 0;
|
||||
|
||||
@override
|
||||
Element get declaration => this;
|
||||
|
||||
@override
|
||||
Element get implementation => this;
|
||||
|
||||
@override
|
||||
bool get isDeclaration => true;
|
||||
|
||||
@override
|
||||
bool get isPatched => false;
|
||||
|
||||
@override
|
||||
bool get isPatch => false;
|
||||
|
||||
@override
|
||||
bool get isImplementation => true;
|
||||
|
||||
@override
|
||||
bool get isInjected => !isPatch && implementationLibrary.isPatch;
|
||||
|
||||
@override
|
||||
Element get patch {
|
||||
throw new UnsupportedError('patch is not supported on $this');
|
||||
}
|
||||
|
||||
@override
|
||||
Element get origin {
|
||||
throw new UnsupportedError('origin is not supported on $this');
|
||||
}
|
||||
}
|
||||
|
||||
abstract class LibraryElementCommon implements LibraryElement {
|
||||
@override
|
||||
bool get isDartCore => canonicalUri == Compiler.DART_CORE;
|
||||
|
||||
@override
|
||||
bool get isPlatformLibrary => canonicalUri.scheme == 'dart';
|
||||
|
||||
@override
|
||||
bool get isPackageLibrary => canonicalUri.scheme == 'package';
|
||||
|
||||
@override
|
||||
bool get isInternalLibrary =>
|
||||
isPlatformLibrary && canonicalUri.path.startsWith('_');
|
||||
}
|
||||
|
||||
abstract class ClassElementCommon implements ClassElement {
|
||||
|
||||
@override
|
||||
Link<DartType> get allSupertypes => allSupertypesAndSelf.supertypes;
|
||||
|
||||
@override
|
||||
int get hierarchyDepth => allSupertypesAndSelf.maxDepth;
|
||||
|
||||
@override
|
||||
InterfaceType asInstanceOf(ClassElement cls) {
|
||||
if (cls == this) return thisType;
|
||||
return allSupertypesAndSelf.asInstanceOf(cls);
|
||||
}
|
||||
|
||||
@override
|
||||
ConstructorElement lookupConstructor(String name) {
|
||||
Element result = localLookup(name);
|
||||
return result != null && result.isConstructor ? result : null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find the first member in the class chain with the given [memberName].
|
||||
*
|
||||
* This method is NOT to be used for resolving
|
||||
* unqualified sends because it does not implement the scoping
|
||||
* rules, where library scope comes before superclass scope.
|
||||
*
|
||||
* When called on the implementation element both members declared in the
|
||||
* origin and the patch class are returned.
|
||||
*/
|
||||
Element lookupByName(Name memberName) {
|
||||
return internalLookupByName(memberName, isSuperLookup: false);
|
||||
}
|
||||
|
||||
Element lookupSuperByName(Name memberName) {
|
||||
return internalLookupByName(memberName, isSuperLookup: true);
|
||||
}
|
||||
|
||||
Element internalLookupByName(Name memberName, {bool isSuperLookup}) {
|
||||
String name = memberName.text;
|
||||
bool isPrivate = memberName.isPrivate;
|
||||
LibraryElement library = memberName.library;
|
||||
for (ClassElement current = isSuperLookup ? superclass : this;
|
||||
current != null;
|
||||
current = current.superclass) {
|
||||
Element member = current.lookupLocalMember(name);
|
||||
if (member == null && current.isPatched) {
|
||||
// Doing lookups on selectors is done after resolution, so it
|
||||
// is safe to look in the patch class.
|
||||
member = current.patch.lookupLocalMember(name);
|
||||
}
|
||||
if (member == null) continue;
|
||||
// Private members from a different library are not visible.
|
||||
if (isPrivate && !identical(library, member.library)) continue;
|
||||
// Static members are not inherited.
|
||||
if (member.isStatic && !identical(this, current)) continue;
|
||||
// If we find an abstract field we have to make sure that it has
|
||||
// the getter or setter part we're actually looking
|
||||
// for. Otherwise, we continue up the superclass chain.
|
||||
if (member.isAbstractField) {
|
||||
AbstractFieldElement field = member;
|
||||
FunctionElement getter = field.getter;
|
||||
FunctionElement setter = field.setter;
|
||||
if (memberName.isSetter) {
|
||||
// Abstract members can be defined in a super class.
|
||||
if (setter != null && !setter.isAbstract) {
|
||||
return setter;
|
||||
}
|
||||
} else {
|
||||
if (getter != null && !getter.isAbstract) {
|
||||
return getter;
|
||||
}
|
||||
}
|
||||
// Abstract members can be defined in a super class.
|
||||
} else if (!member.isAbstract) {
|
||||
return member;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the first member in the class chain with the given
|
||||
* [memberName]. This method is NOT to be used for resolving
|
||||
* unqualified sends because it does not implement the scoping
|
||||
* rules, where library scope comes before superclass scope.
|
||||
*/
|
||||
@override
|
||||
Element lookupMember(String memberName) {
|
||||
Element localMember = lookupLocalMember(memberName);
|
||||
return localMember == null ? lookupSuperMember(memberName) : localMember;
|
||||
}
|
||||
|
||||
@override
|
||||
Link<Element> get constructors {
|
||||
// TODO(ajohnsen): See if we can avoid this method at some point.
|
||||
Link<Element> result = const Link<Element>();
|
||||
// TODO(johnniwinther): Should we include injected constructors?
|
||||
forEachMember((_, Element member) {
|
||||
if (member.isConstructor) result = result.prepend(member);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup super members for the class. This will ignore constructors.
|
||||
*/
|
||||
@override
|
||||
Element lookupSuperMember(String memberName) {
|
||||
return lookupSuperMemberInLibrary(memberName, library);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup super members for the class that is accessible in [library].
|
||||
* This will ignore constructors.
|
||||
*/
|
||||
@override
|
||||
Element lookupSuperMemberInLibrary(String memberName,
|
||||
LibraryElement library) {
|
||||
bool isPrivate = isPrivateName(memberName);
|
||||
for (ClassElement s = superclass; s != null; s = s.superclass) {
|
||||
// Private members from a different library are not visible.
|
||||
if (isPrivate && !identical(library, s.library)) continue;
|
||||
Element e = s.lookupLocalMember(memberName);
|
||||
if (e == null) continue;
|
||||
// Static members are not inherited.
|
||||
if (e.isStatic) continue;
|
||||
return e;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup local members in the class. This will ignore constructors.
|
||||
*/
|
||||
@override
|
||||
Element lookupLocalMember(String memberName) {
|
||||
var result = localLookup(memberName);
|
||||
if (result != null && result.isConstructor) return null;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs through all members of this class.
|
||||
*
|
||||
* The enclosing class is passed to the callback. This is useful when
|
||||
* [includeSuperAndInjectedMembers] is [:true:].
|
||||
*
|
||||
* When called on an implementation element both the members in the origin
|
||||
* and patch class are included.
|
||||
*/
|
||||
// TODO(johnniwinther): Clean up lookup to get rid of the include predicates.
|
||||
@override
|
||||
void forEachMember(void f(ClassElement enclosingClass, Element member),
|
||||
{includeBackendMembers: false,
|
||||
includeSuperAndInjectedMembers: false}) {
|
||||
bool includeInjectedMembers = includeSuperAndInjectedMembers || isPatch;
|
||||
ClassElement classElement = declaration;
|
||||
do {
|
||||
// Iterate through the members in textual order, which requires
|
||||
// to reverse the data structure [localMembers] we created.
|
||||
// Textual order may be important for certain operations, for
|
||||
// example when emitting the initializers of fields.
|
||||
classElement.forEachLocalMember((e) => f(classElement, e));
|
||||
if (includeBackendMembers) {
|
||||
classElement.forEachBackendMember((e) => f(classElement, e));
|
||||
}
|
||||
if (includeInjectedMembers) {
|
||||
if (classElement.patch != null) {
|
||||
classElement.patch.forEachLocalMember((e) {
|
||||
if (!e.isPatch) f(classElement, e);
|
||||
});
|
||||
}
|
||||
}
|
||||
classElement = includeSuperAndInjectedMembers
|
||||
? classElement.superclass
|
||||
: null;
|
||||
} while (classElement != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs through all instance-field members of this class.
|
||||
*
|
||||
* The enclosing class is passed to the callback. This is useful when
|
||||
* [includeSuperAndInjectedMembers] is [:true:].
|
||||
*
|
||||
* When called on the implementation element both the fields declared in the
|
||||
* origin and in the patch are included.
|
||||
*/
|
||||
@override
|
||||
void forEachInstanceField(void f(ClassElement enclosingClass,
|
||||
FieldElement field),
|
||||
{bool includeSuperAndInjectedMembers: false}) {
|
||||
// Filters so that [f] is only invoked with instance fields.
|
||||
void fieldFilter(ClassElement enclosingClass, Element member) {
|
||||
if (member.isInstanceMember && member.kind == ElementKind.FIELD) {
|
||||
f(enclosingClass, member);
|
||||
}
|
||||
}
|
||||
|
||||
forEachMember(fieldFilter,
|
||||
includeSuperAndInjectedMembers: includeSuperAndInjectedMembers);
|
||||
}
|
||||
|
||||
/// Similar to [forEachInstanceField] but visits static fields.
|
||||
@override
|
||||
void forEachStaticField(void f(ClassElement enclosingClass, Element field)) {
|
||||
// Filters so that [f] is only invoked with static fields.
|
||||
void fieldFilter(ClassElement enclosingClass, Element member) {
|
||||
if (!member.isInstanceMember && member.kind == ElementKind.FIELD) {
|
||||
f(enclosingClass, member);
|
||||
}
|
||||
}
|
||||
|
||||
forEachMember(fieldFilter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the [fieldMember] shadows another field. The given
|
||||
* [fieldMember] must be a member of this class, i.e. if there is a field of
|
||||
* the same name in the superclass chain.
|
||||
*
|
||||
* This method also works if the [fieldMember] is private.
|
||||
*/
|
||||
@override
|
||||
bool hasFieldShadowedBy(Element fieldMember) {
|
||||
assert(fieldMember.isField);
|
||||
String fieldName = fieldMember.name;
|
||||
bool isPrivate = isPrivateName(fieldName);
|
||||
LibraryElement memberLibrary = fieldMember.library;
|
||||
ClassElement lookupClass = this.superclass;
|
||||
while (lookupClass != null) {
|
||||
Element foundMember = lookupClass.lookupLocalMember(fieldName);
|
||||
if (foundMember != null) {
|
||||
if (foundMember.isField) {
|
||||
if (!isPrivate || memberLibrary == foundMember.library) {
|
||||
// Private fields can only be shadowed by a field declared in the
|
||||
// same library.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
lookupClass = lookupClass.superclass;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
bool implementsInterface(ClassElement intrface) {
|
||||
for (DartType implementedInterfaceType in allSupertypes) {
|
||||
ClassElement implementedInterface = implementedInterfaceType.element;
|
||||
if (identical(implementedInterface, intrface)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if [this] is a subclass of [cls].
|
||||
*
|
||||
* This method is not to be used for checking type hierarchy and
|
||||
* assignments, because it does not take parameterized types into
|
||||
* account.
|
||||
*/
|
||||
bool isSubclassOf(ClassElement cls) {
|
||||
// Use [declaration] for both [this] and [cls], because
|
||||
// declaration classes hold the superclass hierarchy.
|
||||
cls = cls.declaration;
|
||||
for (ClassElement s = declaration; s != null; s = s.superclass) {
|
||||
if (identical(s, cls)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
FunctionType get callType {
|
||||
MemberSignature member =
|
||||
lookupInterfaceMember(const PublicName(Compiler.CALL_OPERATOR_NAME));
|
||||
return member != null && member.isMethod ? member.type : null;
|
||||
}
|
||||
}
|
||||
|
||||
abstract class FunctionSignatureCommon implements FunctionSignature {
|
||||
void forEachRequiredParameter(void function(Element parameter)) {
|
||||
requiredParameters.forEach(function);
|
||||
}
|
||||
|
||||
void forEachOptionalParameter(void function(Element parameter)) {
|
||||
optionalParameters.forEach(function);
|
||||
}
|
||||
|
||||
Element get firstOptionalParameter => optionalParameters.first;
|
||||
|
||||
void forEachParameter(void function(Element parameter)) {
|
||||
forEachRequiredParameter(function);
|
||||
forEachOptionalParameter(function);
|
||||
}
|
||||
|
||||
void orderedForEachParameter(void function(Element parameter)) {
|
||||
forEachRequiredParameter(function);
|
||||
orderedOptionalParameters.forEach(function);
|
||||
}
|
||||
|
||||
int get parameterCount => requiredParameterCount + optionalParameterCount;
|
||||
|
||||
/**
|
||||
* Check whether a function with this signature can be used instead of a
|
||||
* function with signature [signature] without causing a `noSuchMethod`
|
||||
* exception/call.
|
||||
*/
|
||||
bool isCompatibleWith(FunctionSignature signature) {
|
||||
if (optionalParametersAreNamed) {
|
||||
if (!signature.optionalParametersAreNamed) {
|
||||
return requiredParameterCount == signature.parameterCount;
|
||||
}
|
||||
// If both signatures have named parameters, then they must have
|
||||
// the same number of required parameters, and the names in
|
||||
// [signature] must all be in [:this:].
|
||||
if (requiredParameterCount != signature.requiredParameterCount) {
|
||||
return false;
|
||||
}
|
||||
Set<String> names = optionalParameters.map(
|
||||
(Element element) => element.name).toSet();
|
||||
for (Element namedParameter in signature.optionalParameters) {
|
||||
if (!names.contains(namedParameter.name)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (signature.optionalParametersAreNamed) return false;
|
||||
// There must be at least as many arguments as in the other signature, but
|
||||
// this signature must not have more required parameters. Having more
|
||||
// optional parameters is not a problem, they simply are never provided
|
||||
// by call sites of a call to a method with the other signature.
|
||||
int otherTotalCount = signature.parameterCount;
|
||||
return requiredParameterCount <= otherTotalCount
|
||||
&& parameterCount >= otherTotalCount;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,77 +1,77 @@
|
|||
// Copyright (c) 2012, 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.
|
||||
|
||||
library dart2js.io.line_column;
|
||||
|
||||
import 'code_output.dart';
|
||||
|
||||
/// Interface for providing line/column information.
|
||||
abstract class LineColumnProvider {
|
||||
/// Returns the line number (0-based) for [offset].
|
||||
int getLine(int offset);
|
||||
|
||||
/// Returns the column number (0-based) for [offset] at the given [line].
|
||||
int getColumn(int line, int offset);
|
||||
}
|
||||
|
||||
/// [CodeOutputListener] that collects line information.
|
||||
class LineColumnCollector extends CodeOutputListener
|
||||
implements LineColumnProvider {
|
||||
int length = 0;
|
||||
List<int> lineStarts = <int>[0];
|
||||
|
||||
void _collect(String text) {
|
||||
int index = 0;
|
||||
while (index < text.length) {
|
||||
// Unix uses '\n' and Windows uses '\r\n', so this algorithm works for
|
||||
// both platforms.
|
||||
index = text.indexOf('\n', index) + 1;
|
||||
if (index <= 0) break;
|
||||
lineStarts.add(length + index);
|
||||
}
|
||||
length += text.length;
|
||||
}
|
||||
|
||||
@override
|
||||
void onText(String text) {
|
||||
_collect(text);
|
||||
}
|
||||
|
||||
@override
|
||||
int getLine(int offset) {
|
||||
List<int> starts = lineStarts;
|
||||
if (offset < 0 || starts.last <= offset) {
|
||||
throw 'bad position #$offset in buffer with length ${length}.';
|
||||
}
|
||||
int first = 0;
|
||||
int count = starts.length;
|
||||
while (count > 1) {
|
||||
int step = count ~/ 2;
|
||||
int middle = first + step;
|
||||
int lineStart = starts[middle];
|
||||
if (offset < lineStart) {
|
||||
count = step;
|
||||
} else {
|
||||
first = middle;
|
||||
count -= step;
|
||||
}
|
||||
}
|
||||
return first;
|
||||
}
|
||||
|
||||
@override
|
||||
int getColumn(int line, int offset) {
|
||||
return offset - lineStarts[line];
|
||||
}
|
||||
|
||||
@override
|
||||
void onDone(int length) {
|
||||
lineStarts.add(length + 1);
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
String toString() {
|
||||
return 'lineStarts=$lineStarts,length=$length';
|
||||
}
|
||||
}
|
||||
// Copyright (c) 2012, 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.
|
||||
|
||||
library dart2js.io.line_column;
|
||||
|
||||
import 'code_output.dart';
|
||||
|
||||
/// Interface for providing line/column information.
|
||||
abstract class LineColumnProvider {
|
||||
/// Returns the line number (0-based) for [offset].
|
||||
int getLine(int offset);
|
||||
|
||||
/// Returns the column number (0-based) for [offset] at the given [line].
|
||||
int getColumn(int line, int offset);
|
||||
}
|
||||
|
||||
/// [CodeOutputListener] that collects line information.
|
||||
class LineColumnCollector extends CodeOutputListener
|
||||
implements LineColumnProvider {
|
||||
int length = 0;
|
||||
List<int> lineStarts = <int>[0];
|
||||
|
||||
void _collect(String text) {
|
||||
int index = 0;
|
||||
while (index < text.length) {
|
||||
// Unix uses '\n' and Windows uses '\r\n', so this algorithm works for
|
||||
// both platforms.
|
||||
index = text.indexOf('\n', index) + 1;
|
||||
if (index <= 0) break;
|
||||
lineStarts.add(length + index);
|
||||
}
|
||||
length += text.length;
|
||||
}
|
||||
|
||||
@override
|
||||
void onText(String text) {
|
||||
_collect(text);
|
||||
}
|
||||
|
||||
@override
|
||||
int getLine(int offset) {
|
||||
List<int> starts = lineStarts;
|
||||
if (offset < 0 || starts.last <= offset) {
|
||||
throw 'bad position #$offset in buffer with length ${length}.';
|
||||
}
|
||||
int first = 0;
|
||||
int count = starts.length;
|
||||
while (count > 1) {
|
||||
int step = count ~/ 2;
|
||||
int middle = first + step;
|
||||
int lineStart = starts[middle];
|
||||
if (offset < lineStart) {
|
||||
count = step;
|
||||
} else {
|
||||
first = middle;
|
||||
count -= step;
|
||||
}
|
||||
}
|
||||
return first;
|
||||
}
|
||||
|
||||
@override
|
||||
int getColumn(int line, int offset) {
|
||||
return offset - lineStarts[line];
|
||||
}
|
||||
|
||||
@override
|
||||
void onDone(int length) {
|
||||
lineStarts.add(length + 1);
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
String toString() {
|
||||
return 'lineStarts=$lineStarts,length=$length';
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue