Index: pkg/compiler/lib/src/native/behavior.dart |
diff --git a/pkg/compiler/lib/src/native/behavior.dart b/pkg/compiler/lib/src/native/behavior.dart |
index d0fd80fae80dafaef387537d68d6255e80b377f4..edca67cf53777085ba6d5a4662b11ebf1b9b3277 100644 |
--- a/pkg/compiler/lib/src/native/behavior.dart |
+++ b/pkg/compiler/lib/src/native/behavior.dart |
@@ -3,23 +3,17 @@ |
// BSD-style license that can be found in the LICENSE file. |
import '../common.dart'; |
-import '../common/backend_api.dart' show |
- ForeignResolver; |
-import '../common/resolution.dart' show |
- Parsing, |
- Resolution; |
-import '../compiler.dart' show |
- Compiler; |
+import '../common/backend_api.dart' show ForeignResolver; |
+import '../common/resolution.dart' show Parsing, Resolution; |
+import '../compiler.dart' show Compiler; |
import '../constants/values.dart'; |
-import '../core_types.dart' show |
- CoreTypes; |
+import '../core_types.dart' show CoreTypes; |
import '../dart_types.dart'; |
import '../elements/elements.dart'; |
import '../js/js.dart' as js; |
import '../js_backend/js_backend.dart'; |
import '../tree/tree.dart'; |
-import '../universe/side_effects.dart' show |
- SideEffects; |
+import '../universe/side_effects.dart' show SideEffects; |
import '../util/util.dart'; |
import 'enqueue.dart'; |
@@ -109,7 +103,6 @@ class NativeThrowBehavior { |
* `null` may be returned. |
*/ |
class NativeBehavior { |
- |
/// [DartType]s or [SpecialType]s returned or yielded by the native element. |
final List typesReturned = []; |
@@ -135,7 +128,6 @@ class NativeBehavior { |
static NativeBehavior get CHANGES_OTHER => NativeBehavior._makeChangesOther(); |
static NativeBehavior get DEPENDS_OTHER => NativeBehavior._makeDependsOther(); |
- |
String toString() { |
return 'NativeBehavior(' |
'returns: ${typesReturned}' |
@@ -238,20 +230,17 @@ class NativeBehavior { |
/// latter is used for the type strings of the form '' and 'var'. |
/// [validTags] can be used to restrict which tags are accepted. |
static void processSpecString( |
- DiagnosticReporter reporter, |
- Spannable spannable, |
- String specString, |
+ DiagnosticReporter reporter, Spannable spannable, String specString, |
{Iterable<String> validTags, |
- void setSideEffects(SideEffects newEffects), |
- void setThrows(NativeThrowBehavior throwKind), |
- void setIsAllocation(bool isAllocation), |
- void setUseGvn(bool useGvn), |
- dynamic resolveType(String typeString), |
- List typesReturned, |
- List typesInstantiated, |
- objectType, nullType}) { |
- |
- |
+ void setSideEffects(SideEffects newEffects), |
+ void setThrows(NativeThrowBehavior throwKind), |
+ void setIsAllocation(bool isAllocation), |
+ void setUseGvn(bool useGvn), |
+ dynamic resolveType(String typeString), |
+ List typesReturned, |
+ List typesInstantiated, |
+ objectType, |
+ nullType}) { |
bool seenError = false; |
void reportError(String message) { |
@@ -261,15 +250,21 @@ class NativeBehavior { |
} |
const List<String> knownTags = const [ |
- 'creates', 'returns', 'depends', 'effects', |
- 'throws', 'gvn', 'new']; |
+ 'creates', |
+ 'returns', |
+ 'depends', |
+ 'effects', |
+ 'throws', |
+ 'gvn', |
+ 'new' |
+ ]; |
/// Resolve a type string of one of the three forms: |
/// * 'void' - in which case [onVoid] is called, |
/// * '' or 'var' - in which case [onVar] is called, |
/// * 'T1|...|Tn' - in which case [onType] is called for each resolved Ti. |
void resolveTypesString(String typesString, |
- {onVoid(), onVar(), onType(type)}) { |
+ {onVoid(), onVar(), onType(type)}) { |
// Various things that are not in fact types. |
if (typesString == 'void') { |
if (onVoid != null) { |
@@ -300,13 +295,11 @@ class NativeBehavior { |
return; |
} |
- List<String> specs = specString.split(';') |
- .map((s) => s.trim()) |
- .toList(); |
- if (specs.last == "") specs.removeLast(); // Allow separator to terminate. |
+ List<String> specs = specString.split(';').map((s) => s.trim()).toList(); |
+ if (specs.last == "") specs.removeLast(); // Allow separator to terminate. |
- assert(validTags == null || |
- (validTags.toSet()..removeAll(validTags)).isEmpty); |
+ assert( |
+ validTags == null || (validTags.toSet()..removeAll(validTags)).isEmpty); |
if (validTags == null) validTags = knownTags; |
Map<String, String> values = <String, String>{}; |
@@ -351,42 +344,38 @@ class NativeBehavior { |
String returns = values['returns']; |
if (returns != null) { |
- resolveTypesString(returns, |
- onVar: () { |
- typesReturned.add(objectType); |
- typesReturned.add(nullType); |
- }, |
- onType: (type) { |
- typesReturned.add(type); |
- }); |
+ resolveTypesString(returns, onVar: () { |
+ typesReturned.add(objectType); |
+ typesReturned.add(nullType); |
+ }, onType: (type) { |
+ typesReturned.add(type); |
+ }); |
} |
String creates = values['creates']; |
if (creates != null) { |
- resolveTypesString(creates, |
- onVoid: () { |
- reportError("Invalid type string 'creates:$creates'"); |
- }, |
- onType: (type) { |
- typesInstantiated.add(type); |
- }); |
+ resolveTypesString(creates, onVoid: () { |
+ reportError("Invalid type string 'creates:$creates'"); |
+ }, onType: (type) { |
+ typesInstantiated.add(type); |
+ }); |
} else if (returns != null) { |
- resolveTypesString(returns, |
- onType: (type) { |
- typesInstantiated.add(type); |
- }); |
+ resolveTypesString(returns, onType: (type) { |
+ typesInstantiated.add(type); |
+ }); |
} |
const throwsOption = const <String, NativeThrowBehavior>{ |
'never': NativeThrowBehavior.NEVER, |
'null(1)': NativeThrowBehavior.MAY_THROW_ONLY_ON_FIRST_ARGUMENT_ACCESS, |
'may': NativeThrowBehavior.MAY, |
- 'must': NativeThrowBehavior.MUST }; |
+ 'must': NativeThrowBehavior.MUST |
+ }; |
- const boolOptions = const<String, bool>{'true': true, 'false': false}; |
+ const boolOptions = const <String, bool>{'true': true, 'false': false}; |
- SideEffects sideEffects = processEffects(reportError, |
- values['effects'], values['depends']); |
+ SideEffects sideEffects = |
+ processEffects(reportError, values['effects'], values['depends']); |
NativeThrowBehavior throwsKind = tagValueLookup('throws', throwsOption); |
bool isAllocation = tagValueLookup('new', boolOptions); |
bool useGvn = tagValueLookup('gvn', boolOptions); |
@@ -395,7 +384,7 @@ class NativeBehavior { |
reportError("'new' and 'gvn' are incompatible"); |
} |
- if (seenError) return; // Avoid callbacks. |
+ if (seenError) return; // Avoid callbacks. |
// TODO(sra): Simplify [throwBehavior] using [sideEffects]. |
@@ -406,10 +395,7 @@ class NativeBehavior { |
} |
static SideEffects processEffects( |
- void reportError(String message), |
- String effects, |
- String depends) { |
- |
+ void reportError(String message), String effects, String depends) { |
if (effects == null && depends == null) return null; |
if (effects == null || depends == null) { |
@@ -473,12 +459,8 @@ class NativeBehavior { |
return sideEffects; |
} |
- static NativeBehavior ofJsCall( |
- Send jsCall, |
- DiagnosticReporter reporter, |
- Parsing parsing, |
- CoreTypes coreTypes, |
- ForeignResolver resolver) { |
+ static NativeBehavior ofJsCall(Send jsCall, DiagnosticReporter reporter, |
+ Parsing parsing, CoreTypes coreTypes, ForeignResolver resolver) { |
// The first argument of a JS-call is a string encoding various attributes |
// of the code. |
// |
@@ -489,25 +471,21 @@ class NativeBehavior { |
var argNodes = jsCall.arguments; |
if (argNodes.isEmpty || argNodes.tail.isEmpty) { |
- reporter.reportErrorMessage( |
- jsCall, |
- MessageKind.GENERIC, |
+ reporter.reportErrorMessage(jsCall, MessageKind.GENERIC, |
{'text': "JS expression takes two or more arguments."}); |
return behavior; |
} |
var specArgument = argNodes.head; |
- if (specArgument is !StringNode || specArgument.isInterpolation) { |
- reporter.reportErrorMessage( |
- specArgument, MessageKind.GENERIC, |
+ if (specArgument is! StringNode || specArgument.isInterpolation) { |
+ reporter.reportErrorMessage(specArgument, MessageKind.GENERIC, |
{'text': "JS first argument must be a string literal."}); |
return behavior; |
} |
var codeArgument = argNodes.tail.head; |
- if (codeArgument is !StringNode || codeArgument.isInterpolation) { |
- reporter.reportErrorMessage( |
- codeArgument, MessageKind.GENERIC, |
+ if (codeArgument is! StringNode || codeArgument.isInterpolation) { |
+ reporter.reportErrorMessage(codeArgument, MessageKind.GENERIC, |
{'text': "JS second argument must be a string literal."}); |
return behavior; |
} |
@@ -546,10 +524,7 @@ class NativeBehavior { |
behavior.useGvn = useGvn; |
} |
- processSpecString( |
- reporter, |
- specArgument, |
- specString, |
+ processSpecString(reporter, specArgument, specString, |
setSideEffects: setSideEffects, |
setThrows: setThrows, |
setIsAllocation: setIsAllocation, |
@@ -580,7 +555,7 @@ class NativeBehavior { |
CoreTypes coreTypes, |
ForeignResolver resolver, |
{bool isBuiltin, |
- List<String> validTags}) { |
+ List<String> validTags}) { |
// The first argument of a JS-embedded global call is a string encoding |
// the type of the code. |
// |
@@ -631,10 +606,7 @@ class NativeBehavior { |
behavior.sideEffects.setTo(newEffects); |
} |
- processSpecString( |
- reporter, |
- jsBuiltinOrEmbeddedGlobalCall, |
- specString, |
+ processSpecString(reporter, jsBuiltinOrEmbeddedGlobalCall, specString, |
validTags: validTags, |
resolveType: resolveType, |
setSideEffects: setSideEffects, |
@@ -654,12 +626,7 @@ class NativeBehavior { |
behavior.sideEffects.setTo(new SideEffects()); |
_fillNativeBehaviorOfBuiltinOrEmbeddedGlobal( |
- behavior, |
- jsBuiltinCall, |
- reporter, |
- parsing, |
- coreTypes, |
- resolver, |
+ behavior, jsBuiltinCall, reporter, parsing, coreTypes, resolver, |
isBuiltin: true); |
return behavior; |
@@ -679,19 +646,13 @@ class NativeBehavior { |
behavior.throwBehavior = NativeThrowBehavior.NEVER; |
_fillNativeBehaviorOfBuiltinOrEmbeddedGlobal( |
- behavior, |
- jsEmbeddedGlobalCall, |
- reporter, |
- parsing, |
- coreTypes, |
- resolver, |
- isBuiltin: false, |
- validTags: const ['returns', 'creates']); |
+ behavior, jsEmbeddedGlobalCall, reporter, parsing, coreTypes, resolver, |
+ isBuiltin: false, validTags: const ['returns', 'creates']); |
return behavior; |
} |
- static NativeBehavior ofMethod(FunctionElement method, Compiler compiler) { |
+ static NativeBehavior ofMethod(FunctionElement method, Compiler compiler) { |
FunctionType type = method.computeType(compiler.resolution); |
var behavior = new NativeBehavior(); |
var returnType = type.returnType; |
@@ -707,7 +668,8 @@ class NativeBehavior { |
// TODO(sigmund,sra): consider doing something better for numeric types. |
behavior.typesReturned.add( |
!isInterop || compiler.options.trustJSInteropTypeAnnotations |
- ? returnType : const DynamicType()); |
+ ? returnType |
+ : const DynamicType()); |
if (!type.returnType.isVoid) { |
// Declared types are nullable. |
behavior.typesReturned.add(compiler.coreTypes.nullType); |
@@ -718,10 +680,10 @@ class NativeBehavior { |
// TODO(sra): Optional arguments are currently missing from the |
// DartType. This should be fixed so the following work-around can be |
// removed. |
- method.functionSignature.forEachOptionalParameter( |
- (ParameterElement parameter) { |
- behavior._escape(parameter.type, compiler.resolution); |
- }); |
+ method.functionSignature |
+ .forEachOptionalParameter((ParameterElement parameter) { |
+ behavior._escape(parameter.type, compiler.resolution); |
+ }); |
behavior._overrideWithAnnotations(method, compiler); |
return behavior; |
@@ -735,7 +697,8 @@ class NativeBehavior { |
// TODO(sigmund,sra): consider doing something better for numeric types. |
behavior.typesReturned.add( |
!isInterop || compiler.options.trustJSInteropTypeAnnotations |
- ? type : const DynamicType()); |
+ ? type |
+ : const DynamicType()); |
// Declared types are nullable. |
behavior.typesReturned.add(resolution.coreTypes.nullType); |
behavior._capture(type, resolution, |
@@ -767,16 +730,20 @@ class NativeBehavior { |
} |
NativeEnqueuer enqueuer = compiler.enqueuer.resolution.nativeEnqueuer; |
- var creates = _collect(element, compiler, enqueuer.annotationCreatesClass, |
- lookup); |
- var returns = _collect(element, compiler, enqueuer.annotationReturnsClass, |
- lookup); |
+ var creates = |
+ _collect(element, compiler, enqueuer.annotationCreatesClass, lookup); |
+ var returns = |
+ _collect(element, compiler, enqueuer.annotationReturnsClass, lookup); |
if (creates != null) { |
- typesInstantiated..clear()..addAll(creates); |
+ typesInstantiated |
+ ..clear() |
+ ..addAll(creates); |
} |
if (returns != null) { |
- typesReturned..clear()..addAll(returns); |
+ typesReturned |
+ ..clear() |
+ ..addAll(returns); |
} |
} |
@@ -786,7 +753,7 @@ class NativeBehavior { |
* Returns `null` if no constraints. |
*/ |
static _collect(Element element, Compiler compiler, Element annotationClass, |
- lookup(str)) { |
+ lookup(str)) { |
DiagnosticReporter reporter = compiler.reporter; |
var types = null; |
for (MetadataAnnotation annotation in element.implementation.metadata) { |
@@ -800,8 +767,8 @@ class NativeBehavior { |
Iterable<ConstantValue> fields = constructedObject.fields.values; |
// TODO(sra): Better validation of the constant. |
if (fields.length != 1 || !fields.single.isString) { |
- reporter.internalError(annotation, |
- 'Annotations needs one string: ${annotation.node}'); |
+ reporter.internalError( |
+ annotation, 'Annotations needs one string: ${annotation.node}'); |
} |
StringConstantValue specStringConstant = fields.single; |
String specString = specStringConstant.toDartString().slowToString(); |
@@ -860,7 +827,8 @@ class NativeBehavior { |
} |
if (!compiler.options.trustJSInteropTypeAnnotations || |
- type.isDynamic || type.isObject) { |
+ type.isDynamic || |
+ type.isObject) { |
// By saying that only JS-interop types can be created, we prevent |
// pulling in every other native type (e.g. all of dart:html) when a |
// JS interop API returns dynamic or when we don't trust the type |
@@ -881,10 +849,7 @@ class NativeBehavior { |
} |
static dynamic _parseType( |
- String typeString, |
- Parsing parsing, |
- lookup(name), |
- locationNodeOrElement) { |
+ String typeString, Parsing parsing, lookup(name), locationNodeOrElement) { |
DiagnosticReporter reporter = parsing.reporter; |
if (typeString == '=Object') return SpecialType.JsObject; |
if (typeString == 'dynamic') { |
@@ -895,21 +860,17 @@ class NativeBehavior { |
int index = typeString.indexOf('<'); |
if (index < 1) { |
- reporter.reportErrorMessage( |
- _errorNode(locationNodeOrElement, parsing), |
- MessageKind.GENERIC, |
- {'text': "Type '$typeString' not found."}); |
+ reporter.reportErrorMessage(_errorNode(locationNodeOrElement, parsing), |
+ MessageKind.GENERIC, {'text': "Type '$typeString' not found."}); |
return const DynamicType(); |
} |
type = lookup(typeString.substring(0, index)); |
- if (type != null) { |
+ if (type != null) { |
// TODO(sra): Parse type parameters. |
return type; |
} |
- reporter.reportErrorMessage( |
- _errorNode(locationNodeOrElement, parsing), |
- MessageKind.GENERIC, |
- {'text': "Type '$typeString' not found."}); |
+ reporter.reportErrorMessage(_errorNode(locationNodeOrElement, parsing), |
+ MessageKind.GENERIC, {'text': "Type '$typeString' not found."}); |
return const DynamicType(); |
} |