Version 2.10.0-52.0.dev
Merge commit 'c9b4f1b5d57086e9ac383134c2ec94a5553cb5f3' into 'dev'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3325b41..c9eefa2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,8 @@
* Adds `Abort` method to class `HttpClientRequest`, which allows users
to cancel outgoing HTTP requests and stop following IO operations.
+* A validtion check is added to `path` of class `Cookie`. Having characters
+ ranging from 0x00 to 0x1f and 0x3b (";") will lead to a `FormatException`.
#### `dart:typed_data`
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 46b2b3e..0923d43 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -6273,35 +6273,6 @@
}
_type = type;
}
-
- /// Return the error reported during type inference for this variable, or
- /// `null` if this variable is not a subject of type inference, or there was
- /// no error.
- TopLevelInferenceError get typeInferenceError {
- if (linkedNode != null) {
- return linkedContext.getTypeInferenceError(linkedNode);
- }
-
- // We don't support type inference errors without linking.
- return null;
- }
-
- /// Return `true` if this variable needs the setter.
- bool get _hasSetter {
- if (isConst) {
- return false;
- }
-
- // TODO(scheglov) is this right?
- if (isLate) {
- if (isFinal) {
- return !hasInitializer;
- }
- return true;
- }
-
- return !isFinal;
- }
}
/// A concrete implementation of a [ParameterElement].
@@ -7126,6 +7097,18 @@
@override
DartType get type => ElementTypeProvider.current.getFieldType(this);
+ /// Return the error reported during type inference for this variable, or
+ /// `null` if this variable is not a subject of type inference, or there was
+ /// no error.
+ TopLevelInferenceError get typeInferenceError {
+ if (linkedNode != null) {
+ return linkedContext.getTypeInferenceError(linkedNode);
+ }
+
+ // We don't support type inference errors without linking.
+ return null;
+ }
+
@override
DartType get typeInternal {
if (linkedNode != null) {
@@ -7146,6 +7129,19 @@
}
return super.typeInternal;
}
+
+ /// Return `true` if this variable needs the setter.
+ bool get _hasSetter {
+ if (isConst) {
+ return false;
+ }
+
+ if (isLate) {
+ return !isFinal || !hasInitializer;
+ }
+
+ return !isFinal;
+ }
}
/// Instances of this class are set for fields and top-level variables
diff --git a/pkg/analyzer/lib/src/generated/testing/element_factory.dart b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
index 0a37c30..427d11f 100644
--- a/pkg/analyzer/lib/src/generated/testing/element_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
@@ -261,145 +261,6 @@
_objectElement = null;
}
- static FunctionElementImpl functionElement(String functionName) =>
- functionElement4(functionName, null, null, null, null);
-
- static FunctionElementImpl functionElement2(
- String functionName, DartType returnType) =>
- functionElement3(functionName, returnType, null, null);
-
- static FunctionElementImpl functionElement3(
- String functionName,
- DartType returnType,
- List<TypeDefiningElement> normalParameters,
- List<TypeDefiningElement> optionalParameters) {
- // We don't create parameter elements because we don't have parameter names
- FunctionElementImpl functionElement = FunctionElementImpl(functionName, 0);
- functionElement.returnType = returnType ?? VoidTypeImpl.instance;
- // parameters
- int normalCount = normalParameters == null ? 0 : normalParameters.length;
- int optionalCount =
- optionalParameters == null ? 0 : optionalParameters.length;
- int totalCount = normalCount + optionalCount;
- List<ParameterElement> parameters = List<ParameterElement>(totalCount);
- for (int i = 0; i < totalCount; i++) {
- ParameterElementImpl parameter = ParameterElementImpl("a$i", i);
- if (i < normalCount) {
- parameter.type = _typeDefiningElementType(normalParameters[i]);
- parameter.parameterKind = ParameterKind.REQUIRED;
- } else {
- parameter.type =
- _typeDefiningElementType(optionalParameters[i - normalCount]);
- parameter.parameterKind = ParameterKind.POSITIONAL;
- }
- parameters[i] = parameter;
- }
- functionElement.parameters = parameters;
- // done
- return functionElement;
- }
-
- static FunctionElementImpl functionElement4(
- String functionName,
- ClassElement returnElement,
- List<ClassElement> normalParameters,
- List<String> names,
- List<ClassElement> namedParameters) {
- FunctionElementImpl functionElement = FunctionElementImpl(functionName, 0);
- // parameters
- int normalCount = normalParameters == null ? 0 : normalParameters.length;
- int nameCount = names == null ? 0 : names.length;
- int typeCount = namedParameters == null ? 0 : namedParameters.length;
- if (names != null && nameCount != typeCount) {
- throw StateError(
- "The passed String[] and ClassElement[] arrays had different lengths.");
- }
- int totalCount = normalCount + nameCount;
- List<ParameterElement> parameters = List<ParameterElement>(totalCount);
- for (int i = 0; i < totalCount; i++) {
- if (i < normalCount) {
- ParameterElementImpl parameter = ParameterElementImpl("a$i", i);
- parameter.type = _typeDefiningElementType(normalParameters[i]);
- parameter.parameterKind = ParameterKind.REQUIRED;
- parameters[i] = parameter;
- } else {
- ParameterElementImpl parameter =
- ParameterElementImpl(names[i - normalCount], i);
- parameter.type =
- _typeDefiningElementType(namedParameters[i - normalCount]);
- parameter.parameterKind = ParameterKind.NAMED;
- parameters[i] = parameter;
- }
- }
- functionElement.parameters = parameters;
- // return type
- if (returnElement == null) {
- functionElement.returnType = VoidTypeImpl.instance;
- } else {
- functionElement.returnType = _typeDefiningElementType(returnElement);
- }
- return functionElement;
- }
-
- static FunctionElementImpl functionElement5(
- String functionName, List<ClassElement> normalParameters) =>
- functionElement3(functionName, null, normalParameters, null);
-
- static FunctionElementImpl functionElement6(
- String functionName,
- List<ClassElement> normalParameters,
- List<ClassElement> optionalParameters) =>
- functionElement3(
- functionName, null, normalParameters, optionalParameters);
-
- static FunctionElementImpl functionElement7(
- String functionName,
- List<ClassElement> normalParameters,
- List<String> names,
- List<ClassElement> namedParameters) =>
- functionElement4(
- functionName, null, normalParameters, names, namedParameters);
-
- static FunctionElementImpl functionElement8(
- List<DartType> parameters, DartType returnType,
- {List<DartType> optional, Map<String, DartType> named}) {
- List<ParameterElement> parameterElements = <ParameterElement>[];
- for (int i = 0; i < parameters.length; i++) {
- ParameterElementImpl parameterElement = ParameterElementImpl("a$i", i);
- parameterElement.type = parameters[i];
- parameterElement.parameterKind = ParameterKind.REQUIRED;
- parameterElements.add(parameterElement);
- }
- if (optional != null) {
- int j = parameters.length;
- for (int i = 0; i < optional.length; i++) {
- ParameterElementImpl parameterElement = ParameterElementImpl("o$i", j);
- parameterElement.type = optional[i];
- parameterElement.parameterKind = ParameterKind.POSITIONAL;
- parameterElements.add(parameterElement);
- j++;
- }
- } else if (named != null) {
- int j = parameters.length;
- for (String s in named.keys) {
- ParameterElementImpl parameterElement = ParameterElementImpl(s, j);
- parameterElement.type = named[s];
- parameterElement.parameterKind = ParameterKind.NAMED;
- parameterElements.add(parameterElement);
- }
- }
-
- return functionElementWithParameters("f", returnType, parameterElements);
- }
-
- static FunctionElementImpl functionElementWithParameters(String functionName,
- DartType returnType, List<ParameterElement> parameters) {
- FunctionElementImpl functionElement = FunctionElementImpl(functionName, 0);
- functionElement.returnType = returnType ?? VoidTypeImpl.instance;
- functionElement.parameters = parameters;
- return functionElement;
- }
-
static GenericTypeAliasElementImpl genericTypeAliasElement(String name,
{List<ParameterElement> parameters = const [], DartType returnType}) {
var element = GenericTypeAliasElementImpl(name, -1);
@@ -648,17 +509,4 @@
typeParameter.variance = variance;
return typeParameter;
}
-
- static DartType _typeDefiningElementType(TypeDefiningElement element) {
- if (element is ClassElement) {
- return element.instantiate(
- typeArguments: List.filled(
- element.typeParameters.length,
- DynamicTypeImpl.instance,
- ),
- nullabilitySuffix: NullabilitySuffix.star,
- );
- }
- throw ArgumentError('element: (${element.runtimeType}) $element');
- }
}
diff --git a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
index 727b439..1a6410a 100644
--- a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
@@ -632,12 +632,8 @@
}
TopLevelInferenceError getTypeInferenceError(AstNode node) {
- if (node is DefaultFormalParameter) {
- return getTypeInferenceError(node.parameter);
- } else if (node is MethodDeclaration) {
+ if (node is MethodDeclaration) {
return LazyMethodDeclaration.getTypeInferenceError(node);
- } else if (node is SimpleFormalParameter) {
- return LazyFormalParameter.getTypeInferenceError(node);
} else if (node is VariableDeclaration) {
return LazyVariableDeclaration.getTypeInferenceError(node);
} else {
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index f036ec1..4e67d44 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -1057,7 +1057,7 @@
void validateHasType(AstNode n, PropertyAccessorElement e) {
if (e.hasImplicitReturnType) {
- var variable = e.declaration.variable as NonParameterVariableElementImpl;
+ var variable = e.declaration.variable as PropertyInducingElementImpl;
TopLevelInferenceError error = variable.typeInferenceError;
if (error != null) {
if (error.kind == TopLevelInferenceErrorKind.dependencyCycle) {
diff --git a/pkg/analyzer/test/src/dart/element/element_test.dart b/pkg/analyzer/test/src/dart/element/element_test.dart
index 5518018..1b926d3 100644
--- a/pkg/analyzer/test/src/dart/element/element_test.dart
+++ b/pkg/analyzer/test/src/dart/element/element_test.dart
@@ -1080,112 +1080,129 @@
}
void test_getNamedParameterTypes_namedParameters() {
- TestTypeProvider typeProvider = TestTypeProvider();
- FunctionElement element = ElementFactory.functionElementWithParameters(
- 'f', VoidTypeImpl.instance, [
- ElementFactory.requiredParameter2('a', typeProvider.intType),
- ElementFactory.requiredParameter2('b', typeProvider.dynamicType),
- ElementFactory.namedParameter2('c', typeProvider.stringType),
- ElementFactory.namedParameter2('d', typeProvider.dynamicType)
- ]);
- FunctionTypeImpl type = element.type;
+ var type = functionTypeNone(
+ typeFormals: [],
+ parameters: [
+ requiredParameter(name: 'a', type: intNone),
+ namedParameter(name: 'b', type: doubleNone),
+ namedParameter(name: 'c', type: stringNone),
+ ],
+ returnType: voidNone,
+ );
Map<String, DartType> types = type.namedParameterTypes;
expect(types, hasLength(2));
- expect(types['c'], typeProvider.stringType);
- expect(types['d'], DynamicTypeImpl.instance);
+ expect(types['b'], doubleNone);
+ expect(types['c'], stringNone);
}
void test_getNamedParameterTypes_noNamedParameters() {
- TestTypeProvider typeProvider = TestTypeProvider();
- FunctionElement element = ElementFactory.functionElementWithParameters(
- 'f', VoidTypeImpl.instance, [
- ElementFactory.requiredParameter2('a', typeProvider.intType),
- ElementFactory.requiredParameter2('b', typeProvider.dynamicType),
- ElementFactory.positionalParameter2('c', typeProvider.stringType)
- ]);
- FunctionTypeImpl type = element.type;
+ var type = functionTypeNone(
+ typeFormals: [],
+ parameters: [
+ requiredParameter(type: intNone),
+ requiredParameter(type: doubleNone),
+ positionalParameter(type: stringNone),
+ ],
+ returnType: voidNone,
+ );
Map<String, DartType> types = type.namedParameterTypes;
expect(types, hasLength(0));
}
void test_getNamedParameterTypes_noParameters() {
- FunctionTypeImpl type = ElementFactory.functionElement('f').type;
+ var type = functionTypeNone(
+ typeFormals: [],
+ parameters: [],
+ returnType: voidNone,
+ );
Map<String, DartType> types = type.namedParameterTypes;
expect(types, hasLength(0));
}
void test_getNormalParameterTypes_noNormalParameters() {
- TestTypeProvider typeProvider = TestTypeProvider();
- FunctionElement element = ElementFactory.functionElementWithParameters(
- 'f', VoidTypeImpl.instance, [
- ElementFactory.positionalParameter2('c', typeProvider.stringType),
- ElementFactory.positionalParameter2('d', typeProvider.dynamicType)
- ]);
- FunctionTypeImpl type = element.type;
+ var type = functionTypeNone(
+ typeFormals: [],
+ parameters: [
+ positionalParameter(type: intNone),
+ positionalParameter(type: doubleNone),
+ ],
+ returnType: voidNone,
+ );
List<DartType> types = type.normalParameterTypes;
expect(types, hasLength(0));
}
void test_getNormalParameterTypes_noParameters() {
- FunctionTypeImpl type = ElementFactory.functionElement('f').type;
+ var type = functionTypeNone(
+ typeFormals: [],
+ parameters: [],
+ returnType: voidNone,
+ );
List<DartType> types = type.normalParameterTypes;
expect(types, hasLength(0));
}
void test_getNormalParameterTypes_normalParameters() {
- TestTypeProvider typeProvider = TestTypeProvider();
- FunctionElement element = ElementFactory.functionElementWithParameters(
- 'f', VoidTypeImpl.instance, [
- ElementFactory.requiredParameter2('a', typeProvider.intType),
- ElementFactory.requiredParameter2('b', typeProvider.dynamicType),
- ElementFactory.positionalParameter2('c', typeProvider.stringType)
- ]);
- FunctionTypeImpl type = element.type;
+ var type = functionTypeNone(
+ typeFormals: [],
+ parameters: [
+ requiredParameter(type: intNone),
+ requiredParameter(type: doubleNone),
+ positionalParameter(type: stringNone),
+ ],
+ returnType: voidNone,
+ );
List<DartType> types = type.normalParameterTypes;
expect(types, hasLength(2));
- expect(types[0], typeProvider.intType);
- expect(types[1], DynamicTypeImpl.instance);
+ expect(types[0], intNone);
+ expect(types[1], doubleNone);
}
void test_getOptionalParameterTypes_noOptionalParameters() {
- TestTypeProvider typeProvider = TestTypeProvider();
- FunctionElement element = ElementFactory.functionElementWithParameters(
- 'f', VoidTypeImpl.instance, [
- ElementFactory.requiredParameter2('a', typeProvider.intType),
- ElementFactory.requiredParameter2('b', typeProvider.dynamicType),
- ElementFactory.namedParameter2('c', typeProvider.stringType),
- ElementFactory.namedParameter2('d', typeProvider.dynamicType)
- ]);
- FunctionTypeImpl type = element.type;
+ var type = functionTypeNone(
+ typeFormals: [],
+ parameters: [
+ requiredParameter(name: 'a', type: intNone),
+ namedParameter(name: 'b', type: doubleNone),
+ ],
+ returnType: voidNone,
+ );
List<DartType> types = type.optionalParameterTypes;
expect(types, hasLength(0));
}
void test_getOptionalParameterTypes_noParameters() {
- FunctionTypeImpl type = ElementFactory.functionElement('f').type;
+ var type = functionTypeNone(
+ typeFormals: [],
+ parameters: [],
+ returnType: voidNone,
+ );
List<DartType> types = type.optionalParameterTypes;
expect(types, hasLength(0));
}
void test_getOptionalParameterTypes_optionalParameters() {
- TestTypeProvider typeProvider = TestTypeProvider();
- FunctionElement element = ElementFactory.functionElementWithParameters(
- 'f', VoidTypeImpl.instance, [
- ElementFactory.requiredParameter2('a', typeProvider.intType),
- ElementFactory.requiredParameter2('b', typeProvider.dynamicType),
- ElementFactory.positionalParameter2('c', typeProvider.stringType),
- ElementFactory.positionalParameter2('d', typeProvider.dynamicType)
- ]);
- FunctionTypeImpl type = element.type;
+ var type = functionTypeNone(
+ typeFormals: [],
+ parameters: [
+ requiredParameter(type: intNone),
+ positionalParameter(type: doubleNone),
+ positionalParameter(type: stringNone),
+ ],
+ returnType: voidNone,
+ );
List<DartType> types = type.optionalParameterTypes;
expect(types, hasLength(2));
- expect(types[0], typeProvider.stringType);
- expect(types[1], DynamicTypeImpl.instance);
+ expect(types[0], doubleNone);
+ expect(types[1], stringNone);
}
void test_resolveToBound() {
- FunctionElementImpl f = ElementFactory.functionElement('f');
- FunctionTypeImpl type = f.type;
+ var type = functionTypeNone(
+ typeFormals: [],
+ parameters: [],
+ returnType: voidNone,
+ );
// Returns this.
expect(type.resolveToBound(null), same(type));
diff --git a/pkg/analyzer/test/src/diagnostics/null_safety_read_write_test.dart b/pkg/analyzer/test/src/diagnostics/null_safety_read_write_test.dart
index eaac79c..8729624 100644
--- a/pkg/analyzer/test/src/diagnostics/null_safety_read_write_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/null_safety_read_write_test.dart
@@ -23,52 +23,75 @@
test_final_definitelyAssigned_read() async {
await assertNoErrorsInCode(r'''
-void f() {
- final x;
- x = 0;
- x; // 0
+void f(final x) {
+ x;
}
''');
- _assertAssigned('x; // 0', assigned: true, unassigned: false);
+ _assertAssigned('x;', assigned: true, unassigned: false);
}
test_final_definitelyAssigned_read_prefixNegate() async {
await assertNoErrorsInCode(r'''
-void f() {
- // ignore:unused_local_variable
- final x;
- x = 0;
- -x; // 0
+void f(final x) {
+ -x;
}
''');
- _assertAssigned('x; // 0', assigned: true, unassigned: false);
+ _assertAssigned('x;', assigned: true, unassigned: false);
}
- test_final_definitelyAssigned_write_assignment_simple() async {
+ test_final_definitelyAssigned_readWrite_compoundAssignment() async {
await assertErrorsInCode(r'''
-void f() {
- // ignore:unused_local_variable
- final x;
- x = 0;
- x = 1;
+void f(final x) {
+ x += 1;
}
''', [
- error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_LOCAL, 67, 1),
+ error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_LOCAL, 20, 1),
]);
- _assertAssigned('x = 0', assigned: false, unassigned: true);
- _assertAssigned('x = 1', assigned: true, unassigned: false);
+ _assertAssigned('x +=', assigned: true, unassigned: false);
+ }
+
+ test_final_definitelyAssigned_readWrite_postfixIncrement() async {
+ await assertErrorsInCode(r'''
+void f(final x) {
+ x++;
+}
+''', [
+ error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_LOCAL, 20, 1),
+ ]);
+ _assertAssigned('x++', assigned: true, unassigned: false);
+ }
+
+ test_final_definitelyAssigned_readWrite_prefixIncrement() async {
+ await assertErrorsInCode(r'''
+void f(final x) {
+ ++x;
+}
+''', [
+ error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_LOCAL, 22, 1),
+ ]);
+ _assertAssigned('x;', assigned: true, unassigned: false);
+ }
+
+ test_final_definitelyAssigned_write() async {
+ await assertErrorsInCode(r'''
+void f(final x) {
+ x = 0;
+}
+''', [
+ error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_LOCAL, 20, 1),
+ ]);
+ _assertAssigned('x =', assigned: true, unassigned: false);
}
test_final_definitelyAssigned_write_forEachLoop_identifier() async {
await assertErrorsInCode(r'''
-void f() {
- final x = 0;
+void f(final x) {
for (x in [0, 1, 2]) {
x;
}
}
''', [
- error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_LOCAL, 33, 1),
+ error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_LOCAL, 25, 1),
]);
_assertAssigned('x in', assigned: true, unassigned: false);
}
@@ -88,6 +111,56 @@
_assertAssigned('x()', assigned: false, unassigned: true);
}
+ test_final_definitelyUnassigned_readWrite_compoundAssignment() async {
+ await assertErrorsInCode(r'''
+void f() {
+ // ignore:unused_local_variable
+ final x;
+ x += 1;
+}
+''', [
+ error(CompileTimeErrorCode.READ_POTENTIALLY_UNASSIGNED_FINAL, 58, 1),
+ ]);
+ _assertAssigned('x +=', assigned: false, unassigned: true);
+ }
+
+ test_final_definitelyUnassigned_readWrite_postfixIncrement() async {
+ await assertErrorsInCode(r'''
+void f() {
+ // ignore:unused_local_variable
+ final x;
+ x++;
+}
+''', [
+ error(CompileTimeErrorCode.READ_POTENTIALLY_UNASSIGNED_FINAL, 58, 1),
+ ]);
+ _assertAssigned('x++', assigned: false, unassigned: true);
+ }
+
+ test_final_definitelyUnassigned_readWrite_prefixIncrement() async {
+ await assertErrorsInCode(r'''
+void f() {
+ // ignore:unused_local_variable
+ final x;
+ ++x; // 0
+}
+''', [
+ error(CompileTimeErrorCode.READ_POTENTIALLY_UNASSIGNED_FINAL, 60, 1),
+ ]);
+ _assertAssigned('x; // 0', assigned: false, unassigned: true);
+ }
+
+ test_final_definitelyUnassigned_write() async {
+ await assertNoErrorsInCode(r'''
+void f() {
+ // ignore:unused_local_variable
+ final x;
+ x = 0;
+}
+''');
+ _assertAssigned('x = 0', assigned: false, unassigned: true);
+ }
+
test_final_neither_read() async {
await assertErrorsInCode(r'''
void f(bool b) {
@@ -101,6 +174,65 @@
_assertAssigned('x; // 0', assigned: false, unassigned: false);
}
+ test_final_neither_readWrite_compoundAssignment() async {
+ await assertErrorsInCode(r'''
+void f(bool b) {
+ // ignore:unused_local_variable
+ final x;
+ if (b) x = 0;
+ x += 1;
+}
+''', [
+ error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_LOCAL, 80, 1),
+ error(CompileTimeErrorCode.READ_POTENTIALLY_UNASSIGNED_FINAL, 80, 1),
+ ]);
+ _assertAssigned('x +=', assigned: false, unassigned: false);
+ }
+
+ test_final_neither_readWrite_postfixIncrement() async {
+ await assertErrorsInCode(r'''
+void f(bool b) {
+ // ignore:unused_local_variable
+ final x;
+ if (b) x = 0;
+ x++;
+}
+''', [
+ error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_LOCAL, 80, 1),
+ error(CompileTimeErrorCode.READ_POTENTIALLY_UNASSIGNED_FINAL, 80, 1),
+ ]);
+ _assertAssigned('x++', assigned: false, unassigned: false);
+ }
+
+ test_final_neither_readWrite_prefixIncrement() async {
+ await assertErrorsInCode(r'''
+void f(bool b) {
+ // ignore:unused_local_variable
+ final x;
+ if (b) x = 0;
+ ++x; // 0
+}
+''', [
+ error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_LOCAL, 82, 1),
+ error(CompileTimeErrorCode.READ_POTENTIALLY_UNASSIGNED_FINAL, 82, 1),
+ ]);
+ _assertAssigned('x; // 0', assigned: false, unassigned: false);
+ }
+
+ test_final_neither_write() async {
+ await assertErrorsInCode(r'''
+void f(bool b) {
+ // ignore:unused_local_variable
+ final x;
+ if (b) x = 0;
+ x = 1;
+}
+''', [
+ error(CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_LOCAL, 80, 1),
+ ]);
+ _assertAssigned('x = 1', assigned: false, unassigned: false);
+ }
+
test_lateFinal_definitelyAssigned_read() async {
await assertNoErrorsInCode(r'''
void f() {
@@ -112,6 +244,62 @@
_assertAssigned('x; // 0', assigned: true, unassigned: false);
}
+ test_lateFinal_definitelyAssigned_readWrite_compoundAssignment() async {
+ await assertErrorsInCode(r'''
+void f() {
+ // ignore:unused_local_variable
+ late final x;
+ x = 0;
+ x += 1;
+}
+''', [
+ error(CompileTimeErrorCode.LATE_FINAL_LOCAL_ALREADY_ASSIGNED, 72, 1),
+ ]);
+ _assertAssigned('x +=', assigned: true, unassigned: false);
+ }
+
+ test_lateFinal_definitelyAssigned_readWrite_postfixIncrement() async {
+ await assertErrorsInCode(r'''
+void f() {
+ // ignore:unused_local_variable
+ late final x;
+ x = 0;
+ x++;
+}
+''', [
+ error(CompileTimeErrorCode.LATE_FINAL_LOCAL_ALREADY_ASSIGNED, 72, 1),
+ ]);
+ _assertAssigned('x++', assigned: true, unassigned: false);
+ }
+
+ test_lateFinal_definitelyAssigned_readWrite_prefixIncrement() async {
+ await assertErrorsInCode(r'''
+void f() {
+ // ignore:unused_local_variable
+ late final x;
+ x = 0;
+ ++x; // 0
+}
+''', [
+ error(CompileTimeErrorCode.LATE_FINAL_LOCAL_ALREADY_ASSIGNED, 74, 1),
+ ]);
+ _assertAssigned('x; // 0', assigned: true, unassigned: false);
+ }
+
+ test_lateFinal_definitelyAssigned_write() async {
+ await assertErrorsInCode(r'''
+void f() {
+ // ignore:unused_local_variable
+ late final x;
+ x = 0;
+ x = 1;
+}
+''', [
+ error(CompileTimeErrorCode.LATE_FINAL_LOCAL_ALREADY_ASSIGNED, 72, 1),
+ ]);
+ _assertAssigned('x = 1', assigned: true, unassigned: false);
+ }
+
test_lateFinal_definitelyUnassigned_read() async {
await assertErrorsInCode(r'''
void f() {
@@ -125,10 +313,63 @@
_assertAssigned('x; // 0', assigned: false, unassigned: true);
}
+ test_lateFinal_definitelyUnassigned_readWrite_compoundAssignment() async {
+ await assertErrorsInCode(r'''
+void f() {
+ // ignore:unused_local_variable
+ late final x;
+ x += 1;
+}
+''', [
+ error(CompileTimeErrorCode.DEFINITELY_UNASSIGNED_LATE_LOCAL_VARIABLE, 63,
+ 1),
+ ]);
+ _assertAssigned('x +=', assigned: false, unassigned: true);
+ }
+
+ test_lateFinal_definitelyUnassigned_readWrite_postfixIncrement() async {
+ await assertErrorsInCode(r'''
+void f() {
+ // ignore:unused_local_variable
+ late final x;
+ x++;
+}
+''', [
+ error(CompileTimeErrorCode.DEFINITELY_UNASSIGNED_LATE_LOCAL_VARIABLE, 63,
+ 1),
+ ]);
+ _assertAssigned('x++', assigned: false, unassigned: true);
+ }
+
+ test_lateFinal_definitelyUnassigned_readWrite_prefixIncrement() async {
+ await assertErrorsInCode(r'''
+void f() {
+ // ignore:unused_local_variable
+ late final x;
+ ++x; // 0
+}
+''', [
+ error(CompileTimeErrorCode.DEFINITELY_UNASSIGNED_LATE_LOCAL_VARIABLE, 65,
+ 1),
+ ]);
+ _assertAssigned('x; // 0', assigned: false, unassigned: true);
+ }
+
+ test_lateFinal_definitelyUnassigned_write() async {
+ await assertNoErrorsInCode(r'''
+void f() {
+ // ignore:unused_local_variable
+ late final x;
+ x = 0;
+}
+''');
+ _assertAssigned('x =', assigned: false, unassigned: true);
+ }
+
test_lateFinal_neither_read() async {
await assertNoErrorsInCode(r'''
void f(bool b) {
- late var x;
+ late final x;
if (b) x = 0;
x; // 0
}
@@ -136,6 +377,54 @@
_assertAssigned('x; // 0', assigned: false, unassigned: false);
}
+ test_lateFinal_neither_readWrite_compoundAssignment() async {
+ await assertNoErrorsInCode(r'''
+void f(bool b) {
+ // ignore:unused_local_variable
+ late final x;
+ if (b) x = 0;
+ x += 1;
+}
+''');
+ _assertAssigned('x +=', assigned: false, unassigned: false);
+ }
+
+ test_lateFinal_neither_readWrite_postfixIncrement() async {
+ await assertNoErrorsInCode(r'''
+void f(bool b) {
+ // ignore:unused_local_variable
+ late final x;
+ if (b) x = 0;
+ x++;
+}
+''');
+ _assertAssigned('x++', assigned: false, unassigned: false);
+ }
+
+ test_lateFinal_neither_readWrite_prefixIncrement() async {
+ await assertNoErrorsInCode(r'''
+void f(bool b) {
+ // ignore:unused_local_variable
+ late final x;
+ if (b) x = 0;
+ ++x; // 0
+}
+''');
+ _assertAssigned('x; // 0', assigned: false, unassigned: false);
+ }
+
+ test_lateFinal_neither_write() async {
+ await assertNoErrorsInCode(r'''
+void f(bool b) {
+ // ignore:unused_local_variable
+ late final x;
+ if (b) x = 0;
+ x = 1;
+}
+''');
+ _assertAssigned('x = 1', assigned: false, unassigned: false);
+ }
+
test_lateFinalNullable_definitelyAssigned_read() async {
await assertNoErrorsInCode(r'''
void f() {
@@ -147,6 +436,62 @@
_assertAssigned('x; // 0', assigned: true, unassigned: false);
}
+ test_lateFinalNullable_definitelyAssigned_readWrite_compoundAssignment() async {
+ await assertErrorsInCode(r'''
+void f() {
+ // ignore:unused_local_variable
+ late final int? x;
+ x = 0;
+ x += 1;
+}
+''', [
+ error(CompileTimeErrorCode.LATE_FINAL_LOCAL_ALREADY_ASSIGNED, 77, 1),
+ ]);
+ _assertAssigned('x +=', assigned: true, unassigned: false);
+ }
+
+ test_lateFinalNullable_definitelyAssigned_readWrite_postfixIncrement() async {
+ await assertErrorsInCode(r'''
+void f() {
+ // ignore:unused_local_variable
+ late final int? x;
+ x = 0;
+ x++;
+}
+''', [
+ error(CompileTimeErrorCode.LATE_FINAL_LOCAL_ALREADY_ASSIGNED, 77, 1),
+ ]);
+ _assertAssigned('x++', assigned: true, unassigned: false);
+ }
+
+ test_lateFinalNullable_definitelyAssigned_readWrite_prefixIncrement() async {
+ await assertErrorsInCode(r'''
+void f() {
+ // ignore:unused_local_variable
+ late final int? x;
+ x = 0;
+ ++x; // 0
+}
+''', [
+ error(CompileTimeErrorCode.LATE_FINAL_LOCAL_ALREADY_ASSIGNED, 79, 1),
+ ]);
+ _assertAssigned('x; // 0', assigned: true, unassigned: false);
+ }
+
+ test_lateFinalNullable_definitelyAssigned_write() async {
+ await assertErrorsInCode(r'''
+void f() {
+ // ignore:unused_local_variable
+ late final int? x;
+ x = 0;
+ x = 1;
+}
+''', [
+ error(CompileTimeErrorCode.LATE_FINAL_LOCAL_ALREADY_ASSIGNED, 77, 1),
+ ]);
+ _assertAssigned('x = 1', assigned: true, unassigned: false);
+ }
+
test_lateFinalNullable_definitelyUnassigned_read() async {
await assertErrorsInCode(r'''
void f() {
@@ -160,6 +505,62 @@
_assertAssigned('x; // 0', assigned: false, unassigned: true);
}
+ test_lateFinalNullable_definitelyUnassigned_readWrite_compoundAssignment() async {
+ await assertErrorsInCode(r'''
+void f() {
+ // ignore:unused_local_variable
+ late final int? x;
+ x += 1;
+}
+''', [
+ error(CompileTimeErrorCode.DEFINITELY_UNASSIGNED_LATE_LOCAL_VARIABLE, 68,
+ 1),
+ error(CompileTimeErrorCode.UNCHECKED_USE_OF_NULLABLE_VALUE, 68, 1),
+ ]);
+ _assertAssigned('x +=', assigned: false, unassigned: true);
+ }
+
+ test_lateFinalNullable_definitelyUnassigned_readWrite_postfixIncrement() async {
+ await assertErrorsInCode(r'''
+void f() {
+ // ignore:unused_local_variable
+ late final int? x;
+ x++;
+}
+''', [
+ error(CompileTimeErrorCode.DEFINITELY_UNASSIGNED_LATE_LOCAL_VARIABLE, 68,
+ 1),
+ error(CompileTimeErrorCode.UNCHECKED_USE_OF_NULLABLE_VALUE, 68, 1),
+ ]);
+ _assertAssigned('x++', assigned: false, unassigned: true);
+ }
+
+ test_lateFinalNullable_definitelyUnassigned_readWrite_prefixIncrement() async {
+ await assertErrorsInCode(r'''
+void f() {
+ // ignore:unused_local_variable
+ late final int? x;
+ ++x; // 0
+}
+''', [
+ error(CompileTimeErrorCode.DEFINITELY_UNASSIGNED_LATE_LOCAL_VARIABLE, 70,
+ 1),
+ error(CompileTimeErrorCode.UNCHECKED_USE_OF_NULLABLE_VALUE, 70, 1),
+ ]);
+ _assertAssigned('x; // 0', assigned: false, unassigned: true);
+ }
+
+ test_lateFinalNullable_definitelyUnassigned_write() async {
+ await assertNoErrorsInCode(r'''
+void f() {
+ // ignore:unused_local_variable
+ late final int? x;
+ x = 0;
+}
+''');
+ _assertAssigned('x = 0', assigned: false, unassigned: true);
+ }
+
test_lateFinalNullable_neither_read() async {
await assertNoErrorsInCode(r'''
void f(bool b) {
@@ -171,6 +572,60 @@
_assertAssigned('x; // 0', assigned: false, unassigned: false);
}
+ test_lateFinalNullable_neither_readWrite_compoundAssignment() async {
+ await assertErrorsInCode(r'''
+void f(bool b) {
+ // ignore:unused_local_variable
+ late final int? x;
+ if (b) x = 0;
+ x += 1;
+}
+''', [
+ error(CompileTimeErrorCode.UNCHECKED_USE_OF_NULLABLE_VALUE, 90, 1),
+ ]);
+ _assertAssigned('x +=', assigned: false, unassigned: false);
+ }
+
+ test_lateFinalNullable_neither_readWrite_postfixIncrement() async {
+ await assertErrorsInCode(r'''
+void f(bool b) {
+ // ignore:unused_local_variable
+ late final int? x;
+ if (b) x = 0;
+ x++;
+}
+''', [
+ error(CompileTimeErrorCode.UNCHECKED_USE_OF_NULLABLE_VALUE, 90, 1),
+ ]);
+ _assertAssigned('x++', assigned: false, unassigned: false);
+ }
+
+ test_lateFinalNullable_neither_readWrite_prefixIncrement() async {
+ await assertErrorsInCode(r'''
+void f(bool b) {
+ // ignore:unused_local_variable
+ late final int? x;
+ if (b) x = 0;
+ ++x; // 0
+}
+''', [
+ error(CompileTimeErrorCode.UNCHECKED_USE_OF_NULLABLE_VALUE, 92, 1),
+ ]);
+ _assertAssigned('x; // 0', assigned: false, unassigned: false);
+ }
+
+ test_lateFinalNullable_neither_write() async {
+ await assertNoErrorsInCode(r'''
+void f(bool b) {
+ // ignore:unused_local_variable
+ late final int? x;
+ if (b) x = 0;
+ x = 1;
+}
+''');
+ _assertAssigned('x = 1', assigned: false, unassigned: false);
+ }
+
test_lateFinalPotentiallyNonNullable_definitelyAssigned_read() async {
await assertNoErrorsInCode(r'''
void f<T>(T t) {
@@ -182,6 +637,20 @@
_assertAssigned('x; // 0', assigned: true, unassigned: false);
}
+ test_lateFinalPotentiallyNonNullable_definitelyAssigned_write() async {
+ await assertErrorsInCode(r'''
+void f<T>(T t, T t2) {
+ // ignore:unused_local_variable
+ late final T x;
+ x = t;
+ x = t2;
+}
+''', [
+ error(CompileTimeErrorCode.LATE_FINAL_LOCAL_ALREADY_ASSIGNED, 86, 1),
+ ]);
+ _assertAssigned('x = t2', assigned: true, unassigned: false);
+ }
+
test_lateFinalPotentiallyNonNullable_definitelyUnassigned_read() async {
await assertErrorsInCode(r'''
void f<T>() {
@@ -195,6 +664,17 @@
_assertAssigned('x; // 0', assigned: false, unassigned: true);
}
+ test_lateFinalPotentiallyNonNullable_definitelyUnassigned_write() async {
+ await assertNoErrorsInCode(r'''
+void f<T>(T t) {
+ // ignore:unused_local_variable
+ late final T x;
+ x = t;
+}
+''');
+ _assertAssigned('x = t', assigned: false, unassigned: true);
+ }
+
test_lateFinalPotentiallyNonNullable_neither_read() async {
await assertNoErrorsInCode(r'''
void f<T>(bool b, T t) {
@@ -206,6 +686,18 @@
_assertAssigned('x; // 0', assigned: false, unassigned: false);
}
+ test_lateFinalPotentiallyNonNullable_neither_write() async {
+ await assertNoErrorsInCode(r'''
+void f<T>(bool b, T t, T t2) {
+ // ignore:unused_local_variable
+ late final T x;
+ if (b) x = t;
+ x = t2;
+}
+''');
+ _assertAssigned('x = t2', assigned: false, unassigned: false);
+ }
+
test_lateNullable_definitelyAssigned_read() async {
await assertNoErrorsInCode(r'''
void f() {
@@ -287,6 +779,54 @@
_assertAssigned('x; // 0', assigned: true, unassigned: false);
}
+ test_lateVar_definitelyAssigned_readWrite_compoundAssignment() async {
+ await assertNoErrorsInCode(r'''
+void f() {
+ // ignore:unused_local_variable
+ late var x;
+ x = 0;
+ x += 1;
+}
+''');
+ _assertAssigned('x +=', assigned: true, unassigned: false);
+ }
+
+ test_lateVar_definitelyAssigned_readWrite_postfixIncrement() async {
+ await assertNoErrorsInCode(r'''
+void f() {
+ // ignore:unused_local_variable
+ late var x;
+ x = 0;
+ x++;
+}
+''');
+ _assertAssigned('x++', assigned: true, unassigned: false);
+ }
+
+ test_lateVar_definitelyAssigned_readWrite_prefixIncrement() async {
+ await assertNoErrorsInCode(r'''
+void f() {
+ // ignore:unused_local_variable
+ late var x;
+ x = 0;
+ ++x; // 0
+}
+''');
+ _assertAssigned('x; // 0', assigned: true, unassigned: false);
+ }
+
+ test_lateVar_definitelyAssigned_write() async {
+ await assertNoErrorsInCode(r'''
+void f() {
+ // ignore:unused_local_variable
+ late var x;
+ x = 0;
+ x = 1;
+}
+''');
+ _assertAssigned('x = 1', assigned: true, unassigned: false);
+ }
+
test_lateVar_definitelyUnassigned_read() async {
await assertErrorsInCode(r'''
void f() {
@@ -311,6 +851,54 @@
_assertAssigned('x; // 0', assigned: false, unassigned: false);
}
+ test_lateVar_neither_readWrite_compoundAssignment() async {
+ await assertNoErrorsInCode(r'''
+void f(bool b) {
+ // ignore:unused_local_variable
+ late var x;
+ if (b) x = 0;
+ x += 1;
+}
+''');
+ _assertAssigned('x +=', assigned: false, unassigned: false);
+ }
+
+ test_lateVar_neither_readWrite_postfixIncrement() async {
+ await assertNoErrorsInCode(r'''
+void f(bool b) {
+ // ignore:unused_local_variable
+ late var x;
+ if (b) x = 0;
+ x++;
+}
+''');
+ _assertAssigned('x++', assigned: false, unassigned: false);
+ }
+
+ test_lateVar_neither_readWrite_prefixIncrement() async {
+ await assertNoErrorsInCode(r'''
+void f(bool b) {
+ // ignore:unused_local_variable
+ late var x;
+ if (b) x = 0;
+ ++x; // 0
+}
+''');
+ _assertAssigned('x; // 0', assigned: false, unassigned: false);
+ }
+
+ test_lateVar_neither_write() async {
+ await assertNoErrorsInCode(r'''
+void f(bool b) {
+ // ignore:unused_local_variable
+ late var x;
+ if (b) x = 0;
+ x = 1;
+}
+''');
+ _assertAssigned('x = 1', assigned: false, unassigned: false);
+ }
+
test_notNullable_write_forEachLoop_identifier() async {
await assertNoErrorsInCode(r'''
void f() {
@@ -320,16 +908,26 @@
}
}
''');
+ _assertAssigned('x in', assigned: false, unassigned: true);
_assertAssigned('x; // 0', assigned: true, unassigned: false);
}
test_nullable_definitelyAssigned_read() async {
await assertNoErrorsInCode(r'''
void f(int? x) {
- x; // 0
+ x;
}
''');
- _assertAssigned('x; // 0', assigned: true, unassigned: false);
+ _assertAssigned('x;', assigned: true, unassigned: false);
+ }
+
+ test_nullable_definitelyAssigned_write() async {
+ await assertNoErrorsInCode(r'''
+void f(int? x) {
+ x = 0;
+}
+''');
+ _assertAssigned('x = 0', assigned: true, unassigned: false);
}
test_nullable_definitelyUnassigned_read() async {
@@ -342,6 +940,17 @@
_assertAssigned('x; // 0', assigned: false, unassigned: true);
}
+ test_nullable_definitelyUnassigned_write() async {
+ await assertNoErrorsInCode(r'''
+void f() {
+ // ignore:unused_local_variable
+ int? x;
+ x = 0;
+}
+''');
+ _assertAssigned('x = 0', assigned: false, unassigned: true);
+ }
+
test_nullable_neither_read() async {
await assertNoErrorsInCode(r'''
void f(bool b) {
@@ -353,6 +962,18 @@
_assertAssigned('x; // 0', assigned: false, unassigned: false);
}
+ test_nullable_neither_write() async {
+ await assertNoErrorsInCode(r'''
+void f(bool b) {
+ // ignore:unused_local_variable
+ int? x;
+ if (b) x = 0;
+ x = 1;
+}
+''');
+ _assertAssigned('x = 1', assigned: false, unassigned: false);
+ }
+
test_potentiallyNonNullable_definitelyAssigned_read() async {
await assertNoErrorsInCode(r'''
void f<T>(T x) {
@@ -362,6 +983,15 @@
_assertAssigned('x; // 0', assigned: true, unassigned: false);
}
+ test_potentiallyNonNullable_definitelyAssigned_write() async {
+ await assertNoErrorsInCode(r'''
+void f<T>(T x, T t) {
+ x = t;
+}
+''');
+ _assertAssigned('x = t', assigned: true, unassigned: false);
+ }
+
test_potentiallyNonNullable_definitelyUnassigned_read() async {
await assertErrorsInCode(r'''
void f<T>() {
@@ -378,6 +1008,17 @@
_assertAssigned('x; // 0', assigned: false, unassigned: true);
}
+ test_potentiallyNonNullable_definitelyUnassigned_write() async {
+ await assertNoErrorsInCode(r'''
+void f<T>(T t) {
+ // ignore:unused_local_variable
+ T x;
+ x = t;
+}
+''');
+ _assertAssigned('x = t', assigned: false, unassigned: true);
+ }
+
test_potentiallyNonNullable_neither_read() async {
await assertErrorsInCode(r'''
void f<T>(bool b, T t) {
@@ -395,15 +1036,61 @@
_assertAssigned('x; // 0', assigned: false, unassigned: false);
}
- test_var_definitelyAssigned_read() async {
+ test_potentiallyNonNullable_neither_write() async {
await assertNoErrorsInCode(r'''
-void f() {
- var x;
- x = 0;
- x; // 0
+void f<T>(bool b, T t, T t2) {
+ // ignore:unused_local_variable
+ T x;
+ if (b) x = t;
+ x = t2;
}
''');
- _assertAssigned('x; // 0', assigned: true, unassigned: false);
+ _assertAssigned('x = t2', assigned: false, unassigned: false);
+ }
+
+ test_var_definitelyAssigned_read() async {
+ await assertNoErrorsInCode(r'''
+void f(var x) {
+ x;
+}
+''');
+ _assertAssigned('x;', assigned: true, unassigned: false);
+ }
+
+ test_var_definitelyAssigned_readWrite_compoundAssignment() async {
+ await assertNoErrorsInCode(r'''
+void f(var x) {
+ x += 1;
+}
+''');
+ _assertAssigned('x +=', assigned: true, unassigned: false);
+ }
+
+ test_var_definitelyAssigned_readWrite_postfixIncrement() async {
+ await assertNoErrorsInCode(r'''
+void f(var x) {
+ x++;
+}
+''');
+ _assertAssigned('x++', assigned: true, unassigned: false);
+ }
+
+ test_var_definitelyAssigned_readWrite_prefixIncrement() async {
+ await assertNoErrorsInCode(r'''
+void f(var x) {
+ ++x;
+}
+''');
+ _assertAssigned('x;', assigned: true, unassigned: false);
+ }
+
+ test_var_definitelyAssigned_write() async {
+ await assertNoErrorsInCode(r'''
+void f(var x) {
+ x = 0;
+}
+''');
+ _assertAssigned('x =', assigned: true, unassigned: false);
}
test_var_definitelyUnassigned_read() async {
@@ -416,6 +1103,50 @@
_assertAssigned('x; // 0', assigned: false, unassigned: true);
}
+ test_var_definitelyUnassigned_readWrite_compoundAssignment() async {
+ await assertNoErrorsInCode(r'''
+void f() {
+ // ignore:unused_local_variable
+ var x;
+ x += 0;
+}
+''');
+ _assertAssigned('x +=', assigned: false, unassigned: true);
+ }
+
+ test_var_definitelyUnassigned_readWrite_postfixIncrement() async {
+ await assertNoErrorsInCode(r'''
+void f() {
+ // ignore:unused_local_variable
+ var x;
+ x++;
+}
+''');
+ _assertAssigned('x++', assigned: false, unassigned: true);
+ }
+
+ test_var_definitelyUnassigned_readWrite_prefixIncrement() async {
+ await assertNoErrorsInCode(r'''
+void f() {
+ // ignore:unused_local_variable
+ var x;
+ ++x; // 0
+}
+''');
+ _assertAssigned('x; // 0', assigned: false, unassigned: true);
+ }
+
+ test_var_definitelyUnassigned_write() async {
+ await assertNoErrorsInCode(r'''
+void f() {
+ // ignore:unused_local_variable
+ var x;
+ x = 0;
+}
+''');
+ _assertAssigned('x = 0', assigned: false, unassigned: true);
+ }
+
test_var_neither_read() async {
await assertNoErrorsInCode(r'''
void f(bool b) {
@@ -427,6 +1158,54 @@
_assertAssigned('x; // 0', assigned: false, unassigned: false);
}
+ test_var_neither_readWrite_compoundAssignment() async {
+ await assertNoErrorsInCode(r'''
+void f(bool b) {
+ // ignore:unused_local_variable
+ var x;
+ if (b) x = 0;
+ x += 1;
+}
+''');
+ _assertAssigned('x += 1', assigned: false, unassigned: false);
+ }
+
+ test_var_neither_readWrite_postfixIncrement() async {
+ await assertNoErrorsInCode(r'''
+void f(bool b) {
+ // ignore:unused_local_variable
+ var x;
+ if (b) x = 0;
+ ++x; // 0
+}
+''');
+ _assertAssigned('x; // 0', assigned: false, unassigned: false);
+ }
+
+ test_var_neither_readWrite_prefixIncrement() async {
+ await assertNoErrorsInCode(r'''
+void f(bool b) {
+ // ignore:unused_local_variable
+ var x;
+ if (b) x = 0;
+ x++;
+}
+''');
+ _assertAssigned('x++', assigned: false, unassigned: false);
+ }
+
+ test_var_neither_write() async {
+ await assertNoErrorsInCode(r'''
+void f(bool b) {
+ // ignore:unused_local_variable
+ var x;
+ if (b) x = 0;
+ x = 1;
+}
+''');
+ _assertAssigned('x = 1', assigned: false, unassigned: false);
+ }
+
void _assertAssigned(
String search, {
@required bool assigned,
diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart
index 6d6be56..1158676 100644
--- a/pkg/analyzer/test/src/summary/element_text.dart
+++ b/pkg/analyzer/test/src/summary/element_text.dart
@@ -1029,7 +1029,7 @@
TopLevelInferenceError inferenceError;
if (e is MethodElementImpl) {
inferenceError = e.typeInferenceError;
- } else if (e is NonParameterVariableElementImpl) {
+ } else if (e is PropertyInducingElementImpl) {
inferenceError = e.typeInferenceError;
}
diff --git a/pkg/dartdev/lib/dartdev.dart b/pkg/dartdev/lib/dartdev.dart
index ba32abd..0f031ac 100644
--- a/pkg/dartdev/lib/dartdev.dart
+++ b/pkg/dartdev/lib/dartdev.dart
@@ -17,6 +17,7 @@
import 'src/commands/analyze.dart';
import 'src/commands/compile.dart';
import 'src/commands/create.dart';
+import 'src/commands/fix.dart';
import 'src/commands/pub.dart';
import 'src/commands/run.dart';
import 'src/commands/test.dart';
@@ -205,8 +206,7 @@
addCommand(AnalyzeCommand());
addCommand(CreateCommand(verbose: verbose));
addCommand(CompileCommand());
-// Enable experimental `fix` command
-// addCommand(FixCommand());
+ addCommand(FixCommand());
addCommand(FormatCommand());
addCommand(MigrateCommand(verbose: verbose));
addCommand(PubCommand());
diff --git a/pkg/vm_service/CHANGELOG.md b/pkg/vm_service/CHANGELOG.md
index 90ee11a..e9d92c8 100644
--- a/pkg/vm_service/CHANGELOG.md
+++ b/pkg/vm_service/CHANGELOG.md
@@ -1,5 +1,10 @@
# Changelog
+## Unreleased
+- Added `isSystemIsolate` property to `IsolateRef` and `Isolate`.
+- Added `isSystemIsolateGroup` property to `IsolateGroupRef` and `IsolateGroup`.
+- Added `serviceIsolates` and `serviceIsolateGroups` properties to `VM`.
+
## 4.2.0
- Update to version `3.37.0` of the spec.
- Added `getProcessMemoryUsage` RPC and `ProcessMemoryUsage` and `ProcessMemoryItem` objects.
diff --git a/pkg/vm_service/example/vm_service_assert.dart b/pkg/vm_service/example/vm_service_assert.dart
index 8e64c27..4dc33b5 100644
--- a/pkg/vm_service/example/vm_service_assert.dart
+++ b/pkg/vm_service/example/vm_service_assert.dart
@@ -656,6 +656,7 @@
assertString(obj.id);
assertString(obj.number);
assertString(obj.name);
+ assertBool(obj.isSystemIsolate);
return obj;
}
@@ -672,6 +673,7 @@
assertString(obj.id);
assertString(obj.number);
assertString(obj.name);
+ assertBool(obj.isSystemIsolate);
assertInt(obj.startTime);
assertBool(obj.runnable);
assertInt(obj.livePorts);
@@ -689,6 +691,7 @@
assertString(obj.id);
assertString(obj.number);
assertString(obj.name);
+ assertBool(obj.isSystemIsolateGroup);
return obj;
}
@@ -706,6 +709,7 @@
assertString(obj.id);
assertString(obj.number);
assertString(obj.name);
+ assertBool(obj.isSystemIsolateGroup);
assertListOfIsolateRef(obj.isolates);
return obj;
}
@@ -1193,6 +1197,8 @@
assertInt(obj.startTime);
assertListOfIsolateRef(obj.isolates);
assertListOfIsolateGroupRef(obj.isolateGroups);
+ assertListOfIsolateRef(obj.systemIsolates);
+ assertListOfIsolateGroupRef(obj.systemIsolateGroups);
return obj;
}
diff --git a/pkg/vm_service/java/version.properties b/pkg/vm_service/java/version.properties
index 8e5109e..0fa4741 100644
--- a/pkg/vm_service/java/version.properties
+++ b/pkg/vm_service/java/version.properties
@@ -1 +1 @@
-version=3.37
+version=3.38
diff --git a/pkg/vm_service/lib/src/vm_service.dart b/pkg/vm_service/lib/src/vm_service.dart
index 9fd8aba..8cc7123 100644
--- a/pkg/vm_service/lib/src/vm_service.dart
+++ b/pkg/vm_service/lib/src/vm_service.dart
@@ -28,7 +28,7 @@
HeapSnapshotObjectNoData,
HeapSnapshotObjectNullData;
-const String vmServiceVersion = '3.37.0';
+const String vmServiceVersion = '3.38.0';
/// @optional
const String optional = 'optional';
@@ -4804,16 +4804,22 @@
/// A name identifying this isolate. Not guaranteed to be unique.
String name;
+ /// Specifies whether the isolate was spawned by the VM or embedder for
+ /// internal use. If `false`, this isolate is likely running user code.
+ bool isSystemIsolate;
+
IsolateRef({
@required this.id,
@required this.number,
@required this.name,
+ @required this.isSystemIsolate,
});
IsolateRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
id = json['id'];
number = json['number'];
name = json['name'];
+ isSystemIsolate = json['isSystemIsolate'];
}
@override
@@ -4824,6 +4830,7 @@
'id': id,
'number': number,
'name': name,
+ 'isSystemIsolate': isSystemIsolate,
});
return json;
}
@@ -4832,8 +4839,9 @@
operator ==(other) => other is IsolateRef && id == other.id;
- String toString() =>
- '[IsolateRef type: ${type}, id: ${id}, number: ${number}, name: ${name}]';
+ String toString() => '[IsolateRef ' //
+ 'type: ${type}, id: ${id}, number: ${number}, name: ${name}, ' //
+ 'isSystemIsolate: ${isSystemIsolate}]';
}
/// An `Isolate` object provides information about one isolate in the VM.
@@ -4850,6 +4858,10 @@
/// A name identifying this isolate. Not guaranteed to be unique.
String name;
+ /// Specifies whether the isolate was spawned by the VM or embedder for
+ /// internal use. If `false`, this isolate is likely running user code.
+ bool isSystemIsolate;
+
/// The time that the VM started in milliseconds since the epoch.
///
/// Suitable to pass to DateTime.fromMillisecondsSinceEpoch.
@@ -4898,6 +4910,7 @@
@required this.id,
@required this.number,
@required this.name,
+ @required this.isSystemIsolate,
@required this.startTime,
@required this.runnable,
@required this.livePorts,
@@ -4915,6 +4928,7 @@
id = json['id'];
number = json['number'];
name = json['name'];
+ isSystemIsolate = json['isSystemIsolate'];
startTime = json['startTime'];
runnable = json['runnable'];
livePorts = json['livePorts'];
@@ -4940,6 +4954,7 @@
'id': id,
'number': number,
'name': name,
+ 'isSystemIsolate': isSystemIsolate,
'startTime': startTime,
'runnable': runnable,
'livePorts': livePorts,
@@ -4978,16 +4993,22 @@
/// A name identifying this isolate group. Not guaranteed to be unique.
String name;
+ /// Specifies whether the isolate group was spawned by the VM or embedder for
+ /// internal use. If `false`, this isolate group is likely running user code.
+ bool isSystemIsolateGroup;
+
IsolateGroupRef({
@required this.id,
@required this.number,
@required this.name,
+ @required this.isSystemIsolateGroup,
});
IsolateGroupRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
id = json['id'];
number = json['number'];
name = json['name'];
+ isSystemIsolateGroup = json['isSystemIsolateGroup'];
}
@override
@@ -4998,6 +5019,7 @@
'id': id,
'number': number,
'name': name,
+ 'isSystemIsolateGroup': isSystemIsolateGroup,
});
return json;
}
@@ -5006,8 +5028,9 @@
operator ==(other) => other is IsolateGroupRef && id == other.id;
- String toString() =>
- '[IsolateGroupRef type: ${type}, id: ${id}, number: ${number}, name: ${name}]';
+ String toString() => '[IsolateGroupRef ' //
+ 'type: ${type}, id: ${id}, number: ${number}, name: ${name}, ' //
+ 'isSystemIsolateGroup: ${isSystemIsolateGroup}]';
}
/// An `Isolate` object provides information about one isolate in the VM.
@@ -5024,6 +5047,10 @@
/// A name identifying this isolate. Not guaranteed to be unique.
String name;
+ /// Specifies whether the isolate group was spawned by the VM or embedder for
+ /// internal use. If `false`, this isolate group is likely running user code.
+ bool isSystemIsolateGroup;
+
/// A list of all isolates in this isolate group.
List<IsolateRef> isolates;
@@ -5031,6 +5058,7 @@
@required this.id,
@required this.number,
@required this.name,
+ @required this.isSystemIsolateGroup,
@required this.isolates,
});
@@ -5038,6 +5066,7 @@
id = json['id'];
number = json['number'];
name = json['name'];
+ isSystemIsolateGroup = json['isSystemIsolateGroup'];
isolates = List<IsolateRef>.from(
createServiceObject(json['isolates'], const ['IsolateRef']) ?? []);
}
@@ -5050,6 +5079,7 @@
'id': id,
'number': number,
'name': name,
+ 'isSystemIsolateGroup': isSystemIsolateGroup,
'isolates': isolates.map((f) => f.toJson()).toList(),
});
return json;
@@ -5061,7 +5091,7 @@
String toString() => '[IsolateGroup ' //
'type: ${type}, id: ${id}, number: ${number}, name: ${name}, ' //
- 'isolates: ${isolates}]';
+ 'isSystemIsolateGroup: ${isSystemIsolateGroup}, isolates: ${isolates}]';
}
/// See [getInboundReferences].
@@ -7063,6 +7093,12 @@
/// A list of isolate groups running in the VM.
List<IsolateGroupRef> isolateGroups;
+ /// A list of system isolates running in the VM.
+ List<IsolateRef> systemIsolates;
+
+ /// A list of isolate groups which contain system isolates running in the VM.
+ List<IsolateGroupRef> systemIsolateGroups;
+
VM({
@required this.name,
@required this.architectureBits,
@@ -7074,6 +7110,8 @@
@required this.startTime,
@required this.isolates,
@required this.isolateGroups,
+ @required this.systemIsolates,
+ @required this.systemIsolateGroups,
});
VM._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
@@ -7090,6 +7128,12 @@
isolateGroups = List<IsolateGroupRef>.from(
createServiceObject(json['isolateGroups'], const ['IsolateGroupRef']) ??
[]);
+ systemIsolates = List<IsolateRef>.from(
+ createServiceObject(json['systemIsolates'], const ['IsolateRef']) ??
+ []);
+ systemIsolateGroups = List<IsolateGroupRef>.from(createServiceObject(
+ json['systemIsolateGroups'], const ['IsolateGroupRef']) ??
+ []);
}
@override
@@ -7107,6 +7151,9 @@
'startTime': startTime,
'isolates': isolates.map((f) => f.toJson()).toList(),
'isolateGroups': isolateGroups.map((f) => f.toJson()).toList(),
+ 'systemIsolates': systemIsolates.map((f) => f.toJson()).toList(),
+ 'systemIsolateGroups':
+ systemIsolateGroups.map((f) => f.toJson()).toList(),
});
return json;
}
diff --git a/runtime/bin/dartdev_isolate.cc b/runtime/bin/dartdev_isolate.cc
index b85f8c3..c5a8908 100644
--- a/runtime/bin/dartdev_isolate.cc
+++ b/runtime/bin/dartdev_isolate.cc
@@ -176,6 +176,7 @@
flags.null_safety = false;
flags.use_field_guards = true;
flags.use_osr = true;
+ flags.is_system_isolate = true;
char* error;
Dart_Isolate dartdev_isolate = runner->create_isolate_(
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index d12d6c7..821ae12 100644
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -621,6 +621,7 @@
bool load_vmservice_library;
bool copy_parent_code;
bool null_safety;
+ bool is_system_isolate;
} Dart_IsolateFlags;
/**
diff --git a/runtime/lib/vmservice.cc b/runtime/lib/vmservice.cc
index 95e16c4..eae5565 100644
--- a/runtime/lib/vmservice.cc
+++ b/runtime/lib/vmservice.cc
@@ -29,47 +29,10 @@
: IsolateVisitor(),
register_function_(Function::Handle(thread->zone())),
service_isolate_(thread->isolate()) {
- ASSERT(ServiceIsolate::IsServiceIsolate(Isolate::Current()));
- // Get library.
- const String& library_url = Symbols::DartVMService();
- ASSERT(!library_url.IsNull());
- const Library& library =
- Library::Handle(Library::LookupLibrary(thread, library_url));
- ASSERT(!library.IsNull());
- // Get function.
- const String& function_name =
- String::Handle(String::New("_registerIsolate"));
- ASSERT(!function_name.IsNull());
- register_function_ = library.LookupFunctionAllowPrivate(function_name);
- ASSERT(!register_function_.IsNull());
}
virtual void VisitIsolate(Isolate* isolate) {
- ASSERT(ServiceIsolate::IsServiceIsolate(Isolate::Current()));
- if (!FLAG_show_invisible_isolates && IsVMInternalIsolate(isolate)) {
- // We do not register the service (and descendants), the vm-isolate, or
- // the kernel isolate.
- return;
- }
- // Setup arguments for call.
- Dart_Port port_id = isolate->main_port();
- const Integer& port_int = Integer::Handle(Integer::New(port_id));
- ASSERT(!port_int.IsNull());
- const SendPort& send_port = SendPort::Handle(SendPort::New(port_id));
- const String& name = String::Handle(String::New(isolate->name()));
- ASSERT(!name.IsNull());
- const Array& args = Array::Handle(Array::New(3));
- ASSERT(!args.IsNull());
- args.SetAt(0, port_int);
- args.SetAt(1, send_port);
- args.SetAt(2, name);
- const Object& r =
- Object::Handle(DartEntry::InvokeFunction(register_function_, args));
- if (FLAG_trace_service) {
- OS::PrintErr("vm-service: Isolate %s %" Pd64 " registered.\n",
- name.ToCString(), port_id);
- }
- ASSERT(!r.IsError());
+ ServiceIsolate::RegisterRunningIsolate(isolate);
}
private:
diff --git a/runtime/observatory/lib/src/elements/isolate_ref.dart b/runtime/observatory/lib/src/elements/isolate_ref.dart
index 960661b..344f4b6 100644
--- a/runtime/observatory/lib/src/elements/isolate_ref.dart
+++ b/runtime/observatory/lib/src/elements/isolate_ref.dart
@@ -56,9 +56,10 @@
}
void render() {
+ final isolateType = isolate.isSystemIsolate ? 'System Isolate' : 'Isolate';
children = <Element>[
new AnchorElement(href: Uris.inspect(isolate))
- ..text = 'Isolate ${isolate.number} (${isolate.name})'
+ ..text = '$isolateType ${isolate.number} (${isolate.name})'
..classes = ['isolate-ref']
];
}
diff --git a/runtime/observatory/lib/src/elements/vm_view.dart b/runtime/observatory/lib/src/elements/vm_view.dart
index d183dc3..fed475a 100644
--- a/runtime/observatory/lib/src/elements/vm_view.dart
+++ b/runtime/observatory/lib/src/elements/vm_view.dart
@@ -94,6 +94,9 @@
for (var group in _vm.isolateGroups) {
await _isolateGroups.get(group);
}
+ for (var group in _vm.systemIsolateGroups) {
+ await _isolateGroups.get(group);
+ }
_r.dirty();
}
@@ -115,6 +118,7 @@
describeProcess(),
describeVM(),
describeIsolateGroups(),
+ describeSystemIsolateGroups(),
new ViewFooterElement(queue: _r.queue).element
];
}
@@ -325,14 +329,22 @@
..children = isolateGroups.map(describeIsolateGroup).toList();
}
+ Element describeSystemIsolateGroups() {
+ final isolateGroups = _vm.systemIsolateGroups.toList();
+ return new DivElement()
+ ..children = isolateGroups.map(describeIsolateGroup).toList();
+ }
+
Element describeIsolateGroup(M.IsolateGroupRef group) {
+ final isolateType =
+ group.isSystemIsolateGroup ? 'System Isolate' : 'Isolate';
final isolates = (group as M.IsolateGroup).isolates;
return new DivElement()
..classes = ['content-centered-big']
..children = <Element>[
new HRElement(),
new HeadingElement.h1()
- ..text = "Isolate Group ${group.number} (${group.name})",
+ ..text = "$isolateType Group ${group.number} (${group.name})",
new LIElement()
..classes = ['list-group-item']
..children = <Element>[
diff --git a/runtime/observatory/lib/src/models/objects/isolate.dart b/runtime/observatory/lib/src/models/objects/isolate.dart
index 039e0bd..a3c063a 100644
--- a/runtime/observatory/lib/src/models/objects/isolate.dart
+++ b/runtime/observatory/lib/src/models/objects/isolate.dart
@@ -15,6 +15,9 @@
/// A name identifying this isolate. Not guaranteed to be unique.
String get name;
+ /// True if the isolate is a system isolate which is not running user code.
+ bool get isSystemIsolate;
+
/// Trigger a full GC, collecting all unreachable or weakly reachable objects.
Future collectAllGarbage();
}
diff --git a/runtime/observatory/lib/src/models/objects/isolate_group.dart b/runtime/observatory/lib/src/models/objects/isolate_group.dart
index b18bbf7..7b7a83c 100644
--- a/runtime/observatory/lib/src/models/objects/isolate_group.dart
+++ b/runtime/observatory/lib/src/models/objects/isolate_group.dart
@@ -14,6 +14,8 @@
/// A name identifying this isolate group. Not guaranteed to be unique.
String get name;
+
+ bool get isSystemIsolateGroup;
}
abstract class IsolateGroup extends IsolateGroupRef {
diff --git a/runtime/observatory/lib/src/models/objects/vm.dart b/runtime/observatory/lib/src/models/objects/vm.dart
index ae8210c..b69d744 100644
--- a/runtime/observatory/lib/src/models/objects/vm.dart
+++ b/runtime/observatory/lib/src/models/objects/vm.dart
@@ -51,7 +51,9 @@
// A list of isolates running in the VM.
Iterable<IsolateRef> get isolates;
+ Iterable<IsolateRef> get systemIsolates;
Iterable<IsolateGroupRef> get isolateGroups;
+ Iterable<IsolateGroupRef> get systemIsolateGroups;
/// Enable the sampling profiler.
Future enableProfiler();
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index 9c9c76b..046513d 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -668,8 +668,10 @@
// The list of live isolates, ordered by isolate start time.
final List<Isolate> isolates = <Isolate>[];
+ final List<Isolate> systemIsolates = <Isolate>[];
final List<IsolateGroup> isolateGroups = <IsolateGroup>[];
+ final List<IsolateGroup> systemIsolateGroups = <IsolateGroup>[];
final List<Service> services = <Service>[];
@@ -755,10 +757,17 @@
}
void _buildIsolateList() {
- var isolateList = _isolateCache.values.toList();
+ var isolateList =
+ _isolateCache.values.where((i) => !i.isSystemIsolate).toList();
isolateList.sort(_compareIsolates);
isolates.clear();
isolates.addAll(isolateList);
+
+ var systemIsolateList =
+ _isolateCache.values.where((i) => i.isSystemIsolate).toList();
+ systemIsolateList.sort(_compareIsolates);
+ systemIsolates.clear();
+ systemIsolates.addAll(systemIsolateList);
}
void _removeDeadIsolates(List newIsolates) {
@@ -851,10 +860,18 @@
}
void _buildIsolateGroupList() {
- final isolateGroupList = _isolateGroupCache.values.toList();
+ final isolateGroupList = _isolateGroupCache.values
+ .where((g) => !g.isSystemIsolateGroup)
+ .toList();
isolateGroupList.sort(_compareIsolateGroups);
isolateGroups.clear();
isolateGroups.addAll(isolateGroupList);
+
+ final systemIsolateGroupList =
+ _isolateGroupCache.values.where((g) => g.isSystemIsolateGroup).toList();
+ systemIsolateGroupList.sort(_compareIsolateGroups);
+ systemIsolateGroups.clear();
+ systemIsolateGroups.addAll(systemIsolateGroupList);
}
void _removeDeadIsolateGroups(List newIsolateGroups) {
@@ -1039,8 +1056,14 @@
profileVM = map['_profilerMode'] == 'VM';
assertsEnabled = map['_assertsEnabled'];
typeChecksEnabled = map['_typeChecksEnabled'];
- _removeDeadIsolates(map['isolates']);
- _removeDeadIsolateGroups(map['isolateGroups']);
+ _removeDeadIsolates([
+ ...map['isolates'],
+ ...map['systemIsolates'],
+ ]);
+ _removeDeadIsolateGroups([
+ ...map['isolateGroups'],
+ ...map['systemIsolateGroups'],
+ ]);
}
// Reload all isolates.
@@ -1297,6 +1320,7 @@
name = map['name'];
vmName = map.containsKey('_vmName') ? map['_vmName'] : name;
number = int.tryParse(map['number']);
+ isSystemIsolateGroup = map['isSystemIsolateGroup'];
if (mapIsRef) {
return;
}
@@ -1357,6 +1381,8 @@
@override
int number;
+ bool isSystemIsolateGroup;
+
final Map<String, ServiceObject> _cache = Map<String, ServiceObject>();
}
@@ -1614,6 +1640,8 @@
int get numScopedHandles => _numScopedHandles;
int _numScopedHandles;
+ bool isSystemIsolate;
+
void _loadHeapSnapshot(ServiceEvent event) {
if (_snapshotFetch == null) {
// No outstanding snapshot request. Presumably another client asked for a
@@ -1648,6 +1676,7 @@
name = map['name'];
vmName = map.containsKey('_vmName') ? map['_vmName'] : name;
number = int.tryParse(map['number']);
+ isSystemIsolate = map['isSystemIsolate'];
if (mapIsRef) {
return;
}
diff --git a/runtime/observatory/pubspec.yaml b/runtime/observatory/pubspec.yaml
index 8c4c378..efd6952 100644
--- a/runtime/observatory/pubspec.yaml
+++ b/runtime/observatory/pubspec.yaml
@@ -1,3 +1,11 @@
name: observatory
environment:
- sdk: '>=2.2.2 <3.0.0'
\ No newline at end of file
+ sdk: '>=2.2.2 <3.0.0'
+
+dependencies:
+ usage: 'any'
+
+dev_dependencies:
+ build_runner: '>=1.6.2 <2.0.0'
+ build_web_compilers: '>=2.6.1 <3.0.0'
+
diff --git a/runtime/observatory/tests/service/get_isolate_rpc_test.dart b/runtime/observatory/tests/service/get_isolate_rpc_test.dart
index 293b0d3..adffeb7 100644
--- a/runtime/observatory/tests/service/get_isolate_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_isolate_rpc_test.dart
@@ -16,6 +16,7 @@
expect(result['type'], equals('Isolate'));
expect(result['id'], startsWith('isolates/'));
expect(result['number'], isA<String>());
+ expect(result['isSystemIsolate'], isFalse);
expect(result['_originNumber'], equals(result['number']));
expect(result['startTime'], isPositive);
expect(result['livePorts'], isPositive);
diff --git a/runtime/observatory/tests/service/get_version_rpc_test.dart b/runtime/observatory/tests/service/get_version_rpc_test.dart
index ff51911..37c147a 100644
--- a/runtime/observatory/tests/service/get_version_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_version_rpc_test.dart
@@ -12,7 +12,7 @@
var result = await vm.invokeRpcNoUpgrade('getVersion', {});
expect(result['type'], equals('Version'));
expect(result['major'], equals(3));
- expect(result['minor'], equals(37));
+ expect(result['minor'], equals(38));
expect(result['_privateMajor'], equals(0));
expect(result['_privateMinor'], equals(0));
},
diff --git a/runtime/observatory/tests/service/http_get_isolate_group_rpc_common.dart b/runtime/observatory/tests/service/http_get_isolate_group_rpc_common.dart
index ebe21f5..47ae51c 100644
--- a/runtime/observatory/tests/service/http_get_isolate_group_rpc_common.dart
+++ b/runtime/observatory/tests/service/http_get_isolate_group_rpc_common.dart
@@ -66,6 +66,7 @@
Expect.equals(result['type'], 'IsolateGroup');
Expect.isTrue(result['id'].startsWith('isolateGroups/'));
Expect.type<String>(result['number']);
+ Expect.isFalse(result['isSystemIsolateGroup']);
Expect.isTrue(result['isolates'].length > 0);
Expect.equals(result['isolates'][0]['type'], '@Isolate');
} catch (e) {
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.cc b/runtime/vm/compiler/backend/flow_graph_compiler.cc
index 9bb5958..f33a41c 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc
@@ -262,7 +262,7 @@
if ((FLAG_stacktrace_every > 0) || (FLAG_deoptimize_every > 0) ||
(FLAG_gc_every > 0) ||
(isolate()->reload_every_n_stack_overflow_checks() > 0)) {
- if (!Isolate::IsVMInternalIsolate(isolate())) {
+ if (!Isolate::IsSystemIsolate(isolate())) {
return true;
}
}
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 0ffe978..60a36ec 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -259,13 +259,14 @@
// Setup default flags for the VM isolate.
Dart_IsolateFlags api_flags;
Isolate::FlagsInitialize(&api_flags);
+ api_flags.is_system_isolate = true;
// We make a fake [IsolateGroupSource] here, since the "vm-isolate" is not
// really an isolate itself - it acts more as a container for VM-global
// objects.
- std::unique_ptr<IsolateGroupSource> source(
- new IsolateGroupSource(nullptr, kVmIsolateName, vm_isolate_snapshot,
- instructions_snapshot, nullptr, -1, api_flags));
+ std::unique_ptr<IsolateGroupSource> source(new IsolateGroupSource(
+ kVmIsolateName, kVmIsolateName, vm_isolate_snapshot,
+ instructions_snapshot, nullptr, -1, api_flags));
// ObjectStore should be created later, after null objects are initialized.
auto group = new IsolateGroup(std::move(source), /*embedder_data=*/nullptr,
/*object_store=*/nullptr);
@@ -432,7 +433,7 @@
bool only_aplication_isolates) {
IsolateGroup::ForEach([&](IsolateGroup* group) {
group->ForEachIsolate([&](Isolate* isolate) {
- if (!only_aplication_isolates || !Isolate::IsVMInternalIsolate(isolate)) {
+ if (!only_aplication_isolates || !Isolate::IsSystemIsolate(isolate)) {
OS::PrintErr("Attempt:%" Pd " waiting for isolate %s to check in\n",
num_attempts, isolate->name());
}
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 3669dc2..7f385cb 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -317,12 +317,12 @@
}
bool Debugger::NeedsIsolateEvents() {
- return !Isolate::IsVMInternalIsolate(isolate_) &&
+ return !Isolate::IsSystemIsolate(isolate_) &&
Service::isolate_stream.enabled();
}
bool Debugger::NeedsDebugEvents() {
- ASSERT(!Isolate::IsVMInternalIsolate(isolate_));
+ ASSERT(!Isolate::IsSystemIsolate(isolate_));
return FLAG_warn_on_pause_with_no_debugger || Service::debug_stream.enabled();
}
@@ -1856,7 +1856,7 @@
void Debugger::Shutdown() {
// TODO(johnmccutchan): Do not create a debugger for isolates that don't need
// them. Then, assert here that isolate_ is not one of those isolates.
- if (Isolate::IsVMInternalIsolate(isolate_)) {
+ if (Isolate::IsSystemIsolate(isolate_)) {
return;
}
while (breakpoint_locations_ != NULL) {
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index fb19f98..a4bf348 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -197,8 +197,6 @@
P(enable_isolate_groups, bool, false, "Enable isolate group support.") \
P(show_invisible_frames, bool, false, \
"Show invisible frames in stack traces.") \
- R(show_invisible_isolates, false, bool, false, \
- "Show invisible isolates in the vm-service.") \
R(support_il_printer, false, bool, true, "Support the IL printer.") \
D(trace_cha, bool, false, "Trace CHA operations") \
R(trace_field_guards, false, bool, false, "Trace changes in field's cids.") \
diff --git a/runtime/vm/heap/heap.cc b/runtime/vm/heap/heap.cc
index 170f52c..25a24ce 100644
--- a/runtime/vm/heap/heap.cc
+++ b/runtime/vm/heap/heap.cc
@@ -1009,7 +1009,7 @@
// For now we'll emit the same GC events on all isolates.
if (Service::gc_stream.enabled()) {
isolate_group_->ForEachIsolate([&](Isolate* isolate) {
- if (!Isolate::IsVMInternalIsolate(isolate)) {
+ if (!Isolate::IsSystemIsolate(isolate)) {
ServiceEvent event(isolate, ServiceEvent::kGC);
event.set_gc_stats(&stats_);
Service::HandleEvent(&event);
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 5f37ada..281a6b8 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -345,6 +345,7 @@
isolates_lock_(new SafepointRwLock()),
isolates_(),
start_time_micros_(OS::GetCurrentMonotonicMicros()),
+ is_system_isolate_group_(source->flags.is_system_isolate),
#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
last_reload_timestamp_(OS::GetCurrentTimeMillis()),
#endif
@@ -730,6 +731,7 @@
jsobj->AddProperty("name", source()->script_uri);
jsobj->AddPropertyF("number", "%" Pu64 "", id());
+ jsobj->AddProperty("isSystemIsolateGroup", is_system_isolate_group());
if (ref) {
return;
}
@@ -801,7 +803,7 @@
bool IsolateGroup::HasApplicationIsolateGroups() {
ReadRwLocker wl(ThreadState::Current(), isolate_groups_rwlock_);
for (auto group : *isolate_groups_) {
- if (!IsolateGroup::IsVMInternalIsolateGroup(group)) {
+ if (!IsolateGroup::IsSystemIsolateGroup(group)) {
return true;
}
}
@@ -836,8 +838,8 @@
isolate_groups_ = nullptr;
}
-bool IsolateVisitor::IsVMInternalIsolate(Isolate* isolate) const {
- return Isolate::IsVMInternalIsolate(isolate);
+bool IsolateVisitor::IsSystemIsolate(Isolate* isolate) const {
+ return Isolate::IsSystemIsolate(isolate);
}
NoOOBMessageScope::NoOOBMessageScope(Thread* thread)
@@ -1356,7 +1358,7 @@
}
} else {
#ifndef PRODUCT
- if (!Isolate::IsVMInternalIsolate(I)) {
+ if (!Isolate::IsSystemIsolate(I)) {
// Mark all the user isolates as using a simplified timeline page of
// Observatory. The internal isolates will be filtered out from
// the Timeline due to absence of this argument. We still send them in
@@ -1379,7 +1381,7 @@
#ifndef PRODUCT
void IsolateMessageHandler::NotifyPauseOnStart() {
- if (Isolate::IsVMInternalIsolate(I)) {
+ if (Isolate::IsSystemIsolate(I)) {
return;
}
if (Service::debug_stream.enabled() || FLAG_warn_on_pause_with_no_debugger) {
@@ -1395,7 +1397,7 @@
}
void IsolateMessageHandler::NotifyPauseOnExit() {
- if (Isolate::IsVMInternalIsolate(I)) {
+ if (Isolate::IsSystemIsolate(I)) {
return;
}
if (Service::debug_stream.enabled() || FLAG_warn_on_pause_with_no_debugger) {
@@ -1514,6 +1516,7 @@
api_flags->load_vmservice_library = false;
api_flags->copy_parent_code = false;
api_flags->null_safety = false;
+ api_flags->is_system_isolate = false;
}
void Isolate::FlagsCopyTo(Dart_IsolateFlags* api_flags) const {
@@ -1526,6 +1529,7 @@
api_flags->load_vmservice_library = should_load_vmservice();
api_flags->copy_parent_code = false;
api_flags->null_safety = null_safety();
+ api_flags->is_system_isolate = is_system_isolate();
}
void Isolate::FlagsCopyFrom(const Dart_IsolateFlags& api_flags) {
@@ -1556,7 +1560,7 @@
set_should_load_vmservice(api_flags.load_vmservice_library);
set_null_safety(api_flags.null_safety);
-
+ set_is_system_isolate(api_flags.is_system_isolate);
// Copy entry points list.
ASSERT(embedder_entry_points_ == NULL);
if (api_flags.entry_points != NULL) {
@@ -1960,7 +1964,7 @@
#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
bool Isolate::CanReload() const {
- return !Isolate::IsVMInternalIsolate(this) && is_runnable() &&
+ return !Isolate::IsSystemIsolate(this) && is_runnable() &&
!group()->IsReloading() && (no_reload_scope_depth_ == 0) &&
IsolateCreationEnabled() &&
OSThread::Current()->HasStackHeadroom(64 * KB);
@@ -2059,7 +2063,7 @@
ASSERT(object_store()->root_library() != Library::null());
set_is_runnable(true);
#ifndef PRODUCT
- if (!Isolate::IsVMInternalIsolate(this)) {
+ if (!Isolate::IsSystemIsolate(this)) {
debugger()->OnIsolateRunnable();
if (FLAG_pause_isolates_on_unhandled_exceptions) {
debugger()->SetExceptionPauseInfo(kPauseOnUnhandledExceptions);
@@ -2081,8 +2085,7 @@
}
#endif
#ifndef PRODUCT
- if (!Isolate::IsVMInternalIsolate(this) &&
- Service::isolate_stream.enabled()) {
+ if (!Isolate::IsSystemIsolate(this) && Service::isolate_stream.enabled()) {
ServiceEvent runnableEvent(this, ServiceEvent::kIsolateRunnable);
Service::HandleEvent(&runnableEvent);
}
@@ -2604,8 +2607,7 @@
}
#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
- if (FLAG_check_reloaded && is_runnable() &&
- !Isolate::IsVMInternalIsolate(this)) {
+ if (FLAG_check_reloaded && is_runnable() && !Isolate::IsSystemIsolate(this)) {
if (!HasAttemptedReload()) {
FATAL(
"Isolate did not reload before exiting and "
@@ -3068,6 +3070,7 @@
jsobj.AddProperty("name", name());
jsobj.AddPropertyF("number", "%" Pd64 "", static_cast<int64_t>(main_port()));
+ jsobj.AddProperty("isSystemIsolate", is_system_isolate());
if (ref) {
return;
}
@@ -3435,7 +3438,7 @@
// done atomically.
void Isolate::RegisterServiceExtensionHandler(const String& name,
const Instance& closure) {
- if (Isolate::IsVMInternalIsolate(this)) {
+ if (Isolate::IsSystemIsolate(this)) {
return;
}
GrowableObjectArray& handlers =
@@ -3631,15 +3634,8 @@
return creation_enabled_;
}
-bool IsolateGroup::IsVMInternalIsolateGroup(const IsolateGroup* group) {
- // We use a name comparison here because this method can be called during
- // shutdown, where the actual isolate pointers might've already been cleared.
- const char* name = group->source()->name;
- return Dart::VmIsolateNameEquals(name) ||
-#if !defined(DART_PRECOMPILED_RUNTIME)
- KernelIsolate::NameEquals(name) ||
-#endif
- ServiceIsolate::NameEquals(name);
+bool IsolateGroup::IsSystemIsolateGroup(const IsolateGroup* group) {
+ return group->source()->flags.is_system_isolate;
}
void Isolate::KillLocked(LibMsgId msg_id) {
@@ -3708,7 +3704,7 @@
// If a target_ is specified, then only kill the target_.
// Otherwise, don't kill the service isolate or vm isolate.
return (((target_ != nullptr) && (isolate == target_)) ||
- ((target_ == nullptr) && !IsVMInternalIsolate(isolate)));
+ ((target_ == nullptr) && !IsSystemIsolate(isolate)));
}
Isolate* target_;
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 0e175bd1..f59147d 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -121,7 +121,7 @@
protected:
// Returns true if |isolate| is the VM or service isolate.
- bool IsVMInternalIsolate(Isolate* isolate) const;
+ bool IsSystemIsolate(Isolate* isolate) const;
private:
DISALLOW_COPY_AND_ASSIGN(IsolateVisitor);
@@ -396,6 +396,9 @@
SharedClassTable* shared_class_table() const {
return shared_class_table_.get();
}
+
+ bool is_system_isolate_group() const { return is_system_isolate_group_; }
+
StoreBuffer* store_buffer() const { return store_buffer_.get(); }
ClassTable* class_table() const { return class_table_.get(); }
ObjectStore* object_store() const { return object_store_.get(); }
@@ -562,7 +565,7 @@
static bool HasApplicationIsolateGroups();
static bool HasOnlyVMIsolateGroup();
- static bool IsVMInternalIsolateGroup(const IsolateGroup* group);
+ static bool IsSystemIsolateGroup(const IsolateGroup* group);
int64_t UptimeMicros() const;
@@ -647,6 +650,7 @@
Dart_LibraryTagHandler library_tag_handler_ = nullptr;
Dart_DeferredLoadHandler deferred_load_handler_ = nullptr;
int64_t start_time_micros_;
+ bool is_system_isolate_group_;
#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
int64_t last_reload_timestamp_;
@@ -934,9 +938,7 @@
Mutex* kernel_constants_mutex() { return &kernel_constants_mutex_; }
#if !defined(PRODUCT)
- Debugger* debugger() const {
- return debugger_;
- }
+ Debugger* debugger() const { return debugger_; }
void set_single_step(bool value) { single_step_ = value; }
bool single_step() const { return single_step_; }
@@ -1321,8 +1323,8 @@
static void DisableIsolateCreation();
static void EnableIsolateCreation();
static bool IsolateCreationEnabled();
- static bool IsVMInternalIsolate(const Isolate* isolate) {
- return IsolateGroup::IsVMInternalIsolateGroup(isolate->group());
+ static bool IsSystemIsolate(const Isolate* isolate) {
+ return IsolateGroup::IsSystemIsolateGroup(isolate->group());
}
#if !defined(PRODUCT)
@@ -1399,6 +1401,11 @@
void set_user_tag(uword tag) { user_tag_ = tag; }
+ void set_is_system_isolate(bool is_system_isolate) {
+ is_system_isolate_ = is_system_isolate;
+ }
+ bool is_system_isolate() const { return is_system_isolate_; }
+
#if !defined(PRODUCT)
GrowableObjectArrayPtr GetAndClearPendingServiceExtensionCalls();
GrowableObjectArrayPtr pending_service_extension_calls() const {
@@ -1441,6 +1448,7 @@
ClassPtr* cached_class_table_table_ = nullptr;
FieldTable* field_table_ = nullptr;
bool single_step_ = false;
+ bool is_system_isolate_ = false;
// End accessed from generated code.
IsolateGroup* isolate_group_;
@@ -1544,7 +1552,7 @@
Dart_EnvironmentCallback environment_callback_ = nullptr;
Random random_;
Simulator* simulator_ = nullptr;
- Mutex mutex_; // Protects compiler stats.
+ Mutex mutex_; // Protects compiler stats.
Mutex constant_canonicalization_mutex_; // Protects const canonicalization.
Mutex megamorphic_mutex_; // Protects the table of megamorphic caches and
// their entries.
diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc
index 786c2ed..10b3e76 100644
--- a/runtime/vm/isolate_reload.cc
+++ b/runtime/vm/isolate_reload.cc
@@ -484,7 +484,7 @@
// TODO(dartbug.com/36097): We need to change the "reloadSources" service-api
// call to accept an isolate group instead of an isolate.
Isolate* isolate = Isolate::Current();
- if (Isolate::IsVMInternalIsolate(isolate)) {
+ if (Isolate::IsSystemIsolate(isolate)) {
return;
}
TIR_Print("ISO-RELOAD: Error: %s\n", error.ToErrorCString());
@@ -497,7 +497,7 @@
// TODO(dartbug.com/36097): We need to change the "reloadSources" service-api
// call to accept an isolate group instead of an isolate.
Isolate* isolate = Isolate::Current();
- if (Isolate::IsVMInternalIsolate(isolate)) {
+ if (Isolate::IsSystemIsolate(isolate)) {
return;
}
ServiceEvent service_event(isolate, ServiceEvent::kIsolateReload);
diff --git a/runtime/vm/kernel_isolate.cc b/runtime/vm/kernel_isolate.cc
index 968c212..8fdc9d0 100644
--- a/runtime/vm/kernel_isolate.cc
+++ b/runtime/vm/kernel_isolate.cc
@@ -92,6 +92,7 @@
Dart_IsolateFlags api_flags;
Isolate::FlagsInitialize(&api_flags);
api_flags.enable_asserts = false;
+ api_flags.is_system_isolate = true;
#if !defined(DART_PRECOMPILER)
api_flags.use_field_guards = true;
#endif
diff --git a/runtime/vm/log.cc b/runtime/vm/log.cc
index 9dc6ce0..998ff60 100644
--- a/runtime/vm/log.cc
+++ b/runtime/vm/log.cc
@@ -125,7 +125,7 @@
bool Log::ShouldLogForIsolateGroup(const IsolateGroup* isolate_group) {
if (FLAG_isolate_log_filter == nullptr) {
- if (IsolateGroup::IsVMInternalIsolateGroup(isolate_group)) {
+ if (IsolateGroup::IsSystemIsolateGroup(isolate_group)) {
// By default, do not log for the service or kernel isolates.
return false;
}
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index cf921ac..1d18cae 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -2461,7 +2461,7 @@
isolate->reload_every_n_stack_overflow_checks();
if ((FLAG_deoptimize_every > 0) || (FLAG_stacktrace_every > 0) ||
(FLAG_gc_every > 0) || (isolate_reload_every > 0)) {
- if (!Isolate::IsVMInternalIsolate(isolate)) {
+ if (!Isolate::IsSystemIsolate(isolate)) {
// TODO(turnidge): To make --deoptimize_every and
// --stacktrace-every faster we could move this increment/test to
// the generated code.
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index f82c430..e20e9a9 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -986,8 +986,7 @@
Thread* thread = Thread::Current();
Isolate* isolate = thread->isolate();
ASSERT(isolate != NULL);
- ASSERT(FLAG_show_invisible_isolates ||
- !Isolate::IsVMInternalIsolate(isolate));
+ ASSERT(!Isolate::IsSystemIsolate(isolate));
if (FLAG_trace_service) {
OS::PrintErr(
@@ -1341,10 +1340,10 @@
return -1;
}
Dart_EmbedderInformation info = {
- 0, // version
- NULL, // name
- 0, // max_rss
- 0 // current_rss
+ 0, // version
+ NULL, // name
+ 0, // max_rss
+ 0 // current_rss
};
embedder_information_callback_(&info);
ASSERT(info.version == DART_EMBEDDER_INFORMATION_CURRENT_VERSION);
@@ -1356,10 +1355,10 @@
return -1;
}
Dart_EmbedderInformation info = {
- 0, // version
- NULL, // name
- 0, // max_rss
- 0 // current_rss
+ 0, // version
+ NULL, // name
+ 0, // max_rss
+ 0 // current_rss
};
embedder_information_callback_(&info);
ASSERT(info.version == DART_EMBEDDER_INFORMATION_CURRENT_VERSION);
@@ -1401,7 +1400,8 @@
}
static const MethodParameter* get_isolate_params[] = {
- ISOLATE_PARAMETER, NULL,
+ ISOLATE_PARAMETER,
+ NULL,
};
static bool GetIsolate(Thread* thread, JSONStream* js) {
@@ -2158,7 +2158,8 @@
}
static const MethodParameter* get_inbound_references_params[] = {
- RUNNABLE_ISOLATE_PARAMETER, NULL,
+ RUNNABLE_ISOLATE_PARAMETER,
+ NULL,
};
static bool GetInboundReferences(Thread* thread, JSONStream* js) {
@@ -2275,7 +2276,8 @@
}
static const MethodParameter* get_retaining_path_params[] = {
- RUNNABLE_ISOLATE_PARAMETER, NULL,
+ RUNNABLE_ISOLATE_PARAMETER,
+ NULL,
};
static bool GetRetainingPath(Thread* thread, JSONStream* js) {
@@ -2315,7 +2317,9 @@
}
static const MethodParameter* get_retained_size_params[] = {
- RUNNABLE_ISOLATE_PARAMETER, new IdParameter("targetId", true), NULL,
+ RUNNABLE_ISOLATE_PARAMETER,
+ new IdParameter("targetId", true),
+ NULL,
};
static bool GetRetainedSize(Thread* thread, JSONStream* js) {
@@ -2353,7 +2357,9 @@
}
static const MethodParameter* get_reachable_size_params[] = {
- RUNNABLE_ISOLATE_PARAMETER, new IdParameter("targetId", true), NULL,
+ RUNNABLE_ISOLATE_PARAMETER,
+ new IdParameter("targetId", true),
+ NULL,
};
static bool GetReachableSize(Thread* thread, JSONStream* js) {
@@ -2525,7 +2531,8 @@
}
static const MethodParameter* evaluate_params[] = {
- RUNNABLE_ISOLATE_PARAMETER, NULL,
+ RUNNABLE_ISOLATE_PARAMETER,
+ NULL,
};
static bool IsAlpha(char c) {
@@ -3034,8 +3041,10 @@
}
static const MethodParameter* evaluate_in_frame_params[] = {
- RUNNABLE_ISOLATE_PARAMETER, new UIntParameter("frameIndex", true),
- new MethodParameter("expression", true), NULL,
+ RUNNABLE_ISOLATE_PARAMETER,
+ new UIntParameter("frameIndex", true),
+ new MethodParameter("expression", true),
+ NULL,
};
static bool EvaluateInFrame(Thread* thread, JSONStream* js) {
@@ -3083,7 +3092,8 @@
};
static const MethodParameter* get_instances_params[] = {
- RUNNABLE_ISOLATE_PARAMETER, NULL,
+ RUNNABLE_ISOLATE_PARAMETER,
+ NULL,
};
static bool GetInstances(Thread* thread, JSONStream* js) {
@@ -3379,7 +3389,9 @@
}
static const MethodParameter* add_breakpoint_at_entry_params[] = {
- RUNNABLE_ISOLATE_PARAMETER, new IdParameter("functionId", true), NULL,
+ RUNNABLE_ISOLATE_PARAMETER,
+ new IdParameter("functionId", true),
+ NULL,
};
static bool AddBreakpointAtEntry(Thread* thread, JSONStream* js) {
@@ -3407,7 +3419,9 @@
}
static const MethodParameter* add_breakpoint_at_activation_params[] = {
- RUNNABLE_ISOLATE_PARAMETER, new IdParameter("objectId", true), NULL,
+ RUNNABLE_ISOLATE_PARAMETER,
+ new IdParameter("objectId", true),
+ NULL,
};
static bool AddBreakpointAtActivation(Thread* thread, JSONStream* js) {
@@ -3434,7 +3448,8 @@
}
static const MethodParameter* remove_breakpoint_params[] = {
- RUNNABLE_ISOLATE_PARAMETER, NULL,
+ RUNNABLE_ISOLATE_PARAMETER,
+ NULL,
};
static bool RemoveBreakpoint(Thread* thread, JSONStream* js) {
@@ -3562,7 +3577,8 @@
}
static const MethodParameter* get_isolate_metric_list_params[] = {
- RUNNABLE_ISOLATE_PARAMETER, NULL,
+ RUNNABLE_ISOLATE_PARAMETER,
+ NULL,
};
static bool GetIsolateMetricList(Thread* thread, JSONStream* js) {
@@ -3587,7 +3603,8 @@
}
static const MethodParameter* get_isolate_metric_params[] = {
- RUNNABLE_ISOLATE_PARAMETER, NULL,
+ RUNNABLE_ISOLATE_PARAMETER,
+ NULL,
};
static bool GetIsolateMetric(Thread* thread, JSONStream* js) {
@@ -3617,7 +3634,8 @@
}
static const MethodParameter* get_vm_metric_list_params[] = {
- NO_ISOLATE_PARAMETER, NULL,
+ NO_ISOLATE_PARAMETER,
+ NULL,
};
static bool GetVMMetricList(Thread* thread, JSONStream* js) {
@@ -3625,7 +3643,8 @@
}
static const MethodParameter* get_vm_metric_params[] = {
- NO_ISOLATE_PARAMETER, NULL,
+ NO_ISOLATE_PARAMETER,
+ NULL,
};
static bool GetVMMetric(Thread* thread, JSONStream* js) {
@@ -3698,7 +3717,8 @@
}
static const MethodParameter* get_vm_timeline_flags_params[] = {
- NO_ISOLATE_PARAMETER, NULL,
+ NO_ISOLATE_PARAMETER,
+ NULL,
};
static bool GetVMTimelineFlags(Thread* thread, JSONStream* js) {
@@ -3716,7 +3736,8 @@
}
static const MethodParameter* get_vm_timeline_micros_params[] = {
- NO_ISOLATE_PARAMETER, NULL,
+ NO_ISOLATE_PARAMETER,
+ NULL,
};
static bool GetVMTimelineMicros(Thread* thread, JSONStream* js) {
@@ -3727,7 +3748,8 @@
}
static const MethodParameter* clear_vm_timeline_params[] = {
- NO_ISOLATE_PARAMETER, NULL,
+ NO_ISOLATE_PARAMETER,
+ NULL,
};
static bool ClearVMTimeline(Thread* thread, JSONStream* js) {
@@ -3743,8 +3765,10 @@
}
static const MethodParameter* get_vm_timeline_params[] = {
- NO_ISOLATE_PARAMETER, new Int64Parameter("timeOriginMicros", false),
- new Int64Parameter("timeExtentMicros", false), NULL,
+ NO_ISOLATE_PARAMETER,
+ new Int64Parameter("timeOriginMicros", false),
+ new Int64Parameter("timeExtentMicros", false),
+ NULL,
};
static bool GetVMTimeline(Thread* thread, JSONStream* js) {
@@ -3790,7 +3814,8 @@
static const MethodParameter* resume_params[] = {
RUNNABLE_ISOLATE_PARAMETER,
new EnumParameter("step", false, step_enum_names),
- new UIntParameter("frameIndex", false), NULL,
+ new UIntParameter("frameIndex", false),
+ NULL,
};
static bool Resume(Thread* thread, JSONStream* js) {
@@ -3876,7 +3901,8 @@
}
static const MethodParameter* pause_params[] = {
- RUNNABLE_ISOLATE_PARAMETER, NULL,
+ RUNNABLE_ISOLATE_PARAMETER,
+ NULL,
};
static bool Pause(Thread* thread, JSONStream* js) {
@@ -3905,7 +3931,8 @@
}
static const MethodParameter* get_tag_profile_params[] = {
- RUNNABLE_ISOLATE_PARAMETER, NULL,
+ RUNNABLE_ISOLATE_PARAMETER,
+ NULL,
};
static bool GetTagProfile(Thread* thread, JSONStream* js) {
@@ -4063,7 +4090,8 @@
}
static const MethodParameter* get_heap_map_params[] = {
- RUNNABLE_ISOLATE_PARAMETER, NULL,
+ RUNNABLE_ISOLATE_PARAMETER,
+ NULL,
};
static bool GetHeapMap(Thread* thread, JSONStream* js) {
@@ -4125,71 +4153,73 @@
JSONArray(&profiler, "children");
}
- {
- JSONObject timeline(&vm_children);
- timeline.AddProperty("name", "Timeline");
- timeline.AddProperty(
- "description",
- "Timeline events from dart:developer and Dart_TimelineEvent");
- intptr_t size = Timeline::recorder()->Size();
- vm_size += size;
- timeline.AddProperty64("size", size);
- JSONArray(&timeline, "children");
- }
-
- {
- JSONObject zone(&vm_children);
- zone.AddProperty("name", "Zone");
- zone.AddProperty("description", "Arena allocation in the Dart VM");
- intptr_t size = Zone::Size();
- vm_size += size;
- zone.AddProperty64("size", size);
- JSONArray(&zone, "children");
- }
-
- {
- JSONObject semi(&vm_children);
- semi.AddProperty("name", "SemiSpace Cache");
- semi.AddProperty("description", "Cached heap regions");
- intptr_t size = SemiSpace::CachedSize();
- vm_size += size;
- semi.AddProperty64("size", size);
- JSONArray(&semi, "children");
- }
-
- IsolateGroup::ForEach([&vm_children, &vm_size](IsolateGroup* isolate_group) {
- // Note: new_space()->CapacityInWords() includes memory that hasn't been
- // allocated from the OS yet.
- int64_t capacity = (isolate_group->heap()->new_space()->UsedInWords() +
- isolate_group->heap()->old_space()->CapacityInWords()) *
- kWordSize;
- int64_t used = isolate_group->heap()->TotalUsedInWords() * kWordSize;
- int64_t free = capacity - used;
-
- JSONObject group(&vm_children);
- group.AddPropertyF("name", "IsolateGroup %s",
- isolate_group->source()->name);
- group.AddProperty("description", "Dart heap capacity");
- vm_size += capacity;
- group.AddProperty64("size", capacity);
- JSONArray group_children(&group, "children");
-
{
- JSONObject jsused(&group_children);
- jsused.AddProperty("name", "Used");
- jsused.AddProperty("description", "");
- jsused.AddProperty64("size", used);
- JSONArray(&jsused, "children");
+ JSONObject timeline(&vm_children);
+ timeline.AddProperty("name", "Timeline");
+ timeline.AddProperty(
+ "description",
+ "Timeline events from dart:developer and Dart_TimelineEvent");
+ intptr_t size = Timeline::recorder()->Size();
+ vm_size += size;
+ timeline.AddProperty64("size", size);
+ JSONArray(&timeline, "children");
}
{
- JSONObject jsfree(&group_children);
- jsfree.AddProperty("name", "Free");
- jsfree.AddProperty("description", "");
- jsfree.AddProperty64("size", free);
- JSONArray(&jsfree, "children");
+ JSONObject zone(&vm_children);
+ zone.AddProperty("name", "Zone");
+ zone.AddProperty("description", "Arena allocation in the Dart VM");
+ intptr_t size = Zone::Size();
+ vm_size += size;
+ zone.AddProperty64("size", size);
+ JSONArray(&zone, "children");
}
- });
+
+ {
+ JSONObject semi(&vm_children);
+ semi.AddProperty("name", "SemiSpace Cache");
+ semi.AddProperty("description", "Cached heap regions");
+ intptr_t size = SemiSpace::CachedSize();
+ vm_size += size;
+ semi.AddProperty64("size", size);
+ JSONArray(&semi, "children");
+ }
+
+ IsolateGroup::ForEach(
+ [&vm_children, &vm_size](IsolateGroup* isolate_group) {
+ // Note: new_space()->CapacityInWords() includes memory that hasn't
+ // been allocated from the OS yet.
+ int64_t capacity =
+ (isolate_group->heap()->new_space()->UsedInWords() +
+ isolate_group->heap()->old_space()->CapacityInWords()) *
+ kWordSize;
+ int64_t used = isolate_group->heap()->TotalUsedInWords() * kWordSize;
+ int64_t free = capacity - used;
+
+ JSONObject group(&vm_children);
+ group.AddPropertyF("name", "IsolateGroup %s",
+ isolate_group->source()->name);
+ group.AddProperty("description", "Dart heap capacity");
+ vm_size += capacity;
+ group.AddProperty64("size", capacity);
+ JSONArray group_children(&group, "children");
+
+ {
+ JSONObject jsused(&group_children);
+ jsused.AddProperty("name", "Used");
+ jsused.AddProperty("description", "");
+ jsused.AddProperty64("size", used);
+ JSONArray(&jsused, "children");
+ }
+
+ {
+ JSONObject jsfree(&group_children);
+ jsfree.AddProperty("name", "Free");
+ jsfree.AddProperty("description", "");
+ jsfree.AddProperty64("size", free);
+ JSONArray(&jsfree, "children");
+ }
+ });
} // vm_children
vm.AddProperty("name", "Dart VM");
@@ -4273,7 +4303,8 @@
}
static const MethodParameter* get_persistent_handles_params[] = {
- ISOLATE_PARAMETER, NULL,
+ ISOLATE_PARAMETER,
+ NULL,
};
template <typename T>
@@ -4361,7 +4392,8 @@
}
static const MethodParameter* get_ports_params[] = {
- RUNNABLE_ISOLATE_PARAMETER, NULL,
+ RUNNABLE_ISOLATE_PARAMETER,
+ NULL,
};
static bool GetPorts(Thread* thread, JSONStream* js) {
@@ -4389,8 +4421,10 @@
}
static const MethodParameter* get_object_params[] = {
- RUNNABLE_ISOLATE_PARAMETER, new UIntParameter("offset", false),
- new UIntParameter("count", false), NULL,
+ RUNNABLE_ISOLATE_PARAMETER,
+ new UIntParameter("offset", false),
+ new UIntParameter("count", false),
+ NULL,
};
static bool GetObject(Thread* thread, JSONStream* js) {
@@ -4461,7 +4495,8 @@
}
static const MethodParameter* get_object_store_params[] = {
- RUNNABLE_ISOLATE_PARAMETER, NULL,
+ RUNNABLE_ISOLATE_PARAMETER,
+ NULL,
};
static bool GetObjectStore(Thread* thread, JSONStream* js) {
@@ -4482,7 +4517,8 @@
}
static const MethodParameter* get_class_list_params[] = {
- RUNNABLE_ISOLATE_PARAMETER, NULL,
+ RUNNABLE_ISOLATE_PARAMETER,
+ NULL,
};
static bool GetClassList(Thread* thread, JSONStream* js) {
@@ -4493,7 +4529,8 @@
}
static const MethodParameter* get_type_arguments_list_params[] = {
- RUNNABLE_ISOLATE_PARAMETER, NULL,
+ RUNNABLE_ISOLATE_PARAMETER,
+ NULL,
};
static bool GetTypeArgumentsList(Thread* thread, JSONStream* js) {
@@ -4529,7 +4566,8 @@
}
static const MethodParameter* get_version_params[] = {
- NO_ISOLATE_PARAMETER, NULL,
+ NO_ISOLATE_PARAMETER,
+ NULL,
};
static bool GetVersion(Thread* thread, JSONStream* js) {
@@ -4550,7 +4588,23 @@
virtual ~ServiceIsolateVisitor() {}
void VisitIsolate(Isolate* isolate) {
- if (FLAG_show_invisible_isolates || !IsVMInternalIsolate(isolate)) {
+ if (!IsSystemIsolate(isolate)) {
+ jsarr_->AddValue(isolate);
+ }
+ }
+
+ private:
+ JSONArray* jsarr_;
+};
+
+class SystemServiceIsolateVisitor : public IsolateVisitor {
+ public:
+ explicit SystemServiceIsolateVisitor(JSONArray* jsarr) : jsarr_(jsarr) {}
+ virtual ~SystemServiceIsolateVisitor() {}
+
+ void VisitIsolate(Isolate* isolate) {
+ if (IsSystemIsolate(isolate) &&
+ !Dart::VmIsolateNameEquals(isolate->name())) {
jsarr_->AddValue(isolate);
}
}
@@ -4560,16 +4614,17 @@
};
static const MethodParameter* get_vm_params[] = {
- NO_ISOLATE_PARAMETER, NULL,
+ NO_ISOLATE_PARAMETER,
+ NULL,
};
-void Service::PrintJSONForEmbedderInformation(JSONObject *jsobj) {
+void Service::PrintJSONForEmbedderInformation(JSONObject* jsobj) {
if (embedder_information_callback_ != NULL) {
Dart_EmbedderInformation info = {
- 0, // version
- NULL, // name
- -1, // max_rss
- -1 // current_rss
+ 0, // version
+ NULL, // name
+ -1, // max_rss
+ -1 // current_rss
};
embedder_information_callback_(&info);
ASSERT(info.version == DART_EMBEDDER_INFORMATION_CURRENT_VERSION);
@@ -4612,15 +4667,26 @@
Isolate::VisitIsolates(&visitor);
}
{
+ JSONArray jsarr(&jsobj, "systemIsolates");
+ SystemServiceIsolateVisitor visitor(&jsarr);
+ Isolate::VisitIsolates(&visitor);
+ }
+ {
JSONArray jsarr_isolate_groups(&jsobj, "isolateGroups");
IsolateGroup::ForEach([&jsarr_isolate_groups](IsolateGroup* isolate_group) {
- bool has_internal = false;
- isolate_group->ForEachIsolate([&has_internal](Isolate* isolate) {
- if (Isolate::IsVMInternalIsolate(isolate)) {
- has_internal = true;
- }
- });
- if (FLAG_show_invisible_isolates || !has_internal) {
+ if (!isolate_group->is_system_isolate_group()) {
+ jsarr_isolate_groups.AddValue(isolate_group);
+ }
+ });
+ }
+ {
+ JSONArray jsarr_isolate_groups(&jsobj, "systemIsolateGroups");
+ IsolateGroup::ForEach([&jsarr_isolate_groups](IsolateGroup* isolate_group) {
+ // Don't surface the vm-isolate since it's not a "real" isolate.
+ if (Dart::VmIsolateNameEquals(isolate_group->source()->name)) {
+ return;
+ }
+ if (isolate_group->is_system_isolate_group()) {
jsarr_isolate_groups.AddValue(isolate_group);
}
});
@@ -4638,17 +4704,23 @@
}
static const char* exception_pause_mode_names[] = {
- "All", "None", "Unhandled", NULL,
+ "All",
+ "None",
+ "Unhandled",
+ NULL,
};
static Dart_ExceptionPauseInfo exception_pause_mode_values[] = {
- kPauseOnAllExceptions, kNoPauseOnExceptions, kPauseOnUnhandledExceptions,
+ kPauseOnAllExceptions,
+ kNoPauseOnExceptions,
+ kPauseOnUnhandledExceptions,
kInvalidExceptionPauseInfo,
};
static const MethodParameter* set_exception_pause_mode_params[] = {
ISOLATE_PARAMETER,
- new EnumParameter("mode", true, exception_pause_mode_names), NULL,
+ new EnumParameter("mode", true, exception_pause_mode_names),
+ NULL,
};
static bool SetExceptionPauseMode(Thread* thread, JSONStream* js) {
@@ -4674,7 +4746,8 @@
}
static const MethodParameter* get_flag_list_params[] = {
- NO_ISOLATE_PARAMETER, NULL,
+ NO_ISOLATE_PARAMETER,
+ NULL,
};
static bool GetFlagList(Thread* thread, JSONStream* js) {
@@ -4683,7 +4756,8 @@
}
static const MethodParameter* set_flags_params[] = {
- NO_ISOLATE_PARAMETER, NULL,
+ NO_ISOLATE_PARAMETER,
+ NULL,
};
static bool SetFlag(Thread* thread, JSONStream* js) {
@@ -4763,8 +4837,10 @@
}
static const MethodParameter* set_library_debuggable_params[] = {
- RUNNABLE_ISOLATE_PARAMETER, new IdParameter("libraryId", true),
- new BoolParameter("isDebuggable", true), NULL,
+ RUNNABLE_ISOLATE_PARAMETER,
+ new IdParameter("libraryId", true),
+ new BoolParameter("isDebuggable", true),
+ NULL,
};
static bool SetLibraryDebuggable(Thread* thread, JSONStream* js) {
@@ -4785,7 +4861,9 @@
}
static const MethodParameter* set_name_params[] = {
- ISOLATE_PARAMETER, new MethodParameter("name", true), NULL,
+ ISOLATE_PARAMETER,
+ new MethodParameter("name", true),
+ NULL,
};
static bool SetName(Thread* thread, JSONStream* js) {
@@ -4800,7 +4878,9 @@
}
static const MethodParameter* set_vm_name_params[] = {
- NO_ISOLATE_PARAMETER, new MethodParameter("name", true), NULL,
+ NO_ISOLATE_PARAMETER,
+ new MethodParameter("name", true),
+ NULL,
};
static bool SetVMName(Thread* thread, JSONStream* js) {
@@ -4816,8 +4896,10 @@
}
static const MethodParameter* set_trace_class_allocation_params[] = {
- RUNNABLE_ISOLATE_PARAMETER, new IdParameter("classId", true),
- new BoolParameter("enable", true), NULL,
+ RUNNABLE_ISOLATE_PARAMETER,
+ new IdParameter("classId", true),
+ new BoolParameter("enable", true),
+ NULL,
};
static bool SetTraceClassAllocation(Thread* thread, JSONStream* js) {
@@ -4842,7 +4924,8 @@
}
static const MethodParameter* get_default_classes_aliases_params[] = {
- NO_ISOLATE_PARAMETER, NULL,
+ NO_ISOLATE_PARAMETER,
+ NULL,
};
static bool GetDefaultClassesAliases(Thread* thread, JSONStream* js) {
diff --git a/runtime/vm/service.h b/runtime/vm/service.h
index 6488425..896c695 100644
--- a/runtime/vm/service.h
+++ b/runtime/vm/service.h
@@ -15,7 +15,7 @@
namespace dart {
#define SERVICE_PROTOCOL_MAJOR_VERSION 3
-#define SERVICE_PROTOCOL_MINOR_VERSION 37
+#define SERVICE_PROTOCOL_MINOR_VERSION 38
class Array;
class EmbedderServiceHandler;
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index 281f21b..4ba84da 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -1,8 +1,8 @@
-# Dart VM Service Protocol 3.37
+# Dart VM Service Protocol 3.38
> Please post feedback to the [observatory-discuss group][discuss-list]
-This document describes of _version 3.37_ of the Dart VM Service Protocol. This
+This document describes of _version 3.38_ of the Dart VM Service Protocol. This
protocol is used to communicate with a running Dart Virtual Machine.
To use the Service Protocol, start the VM with the *--observe* flag.
@@ -2858,6 +2858,10 @@
// A name identifying this isolate. Not guaranteed to be unique.
string name;
+
+ // Specifies whether the isolate was spawned by the VM or embedder for
+ // internal use. If `false`, this isolate is likely running user code.
+ bool isSystemIsolate;
}
```
@@ -2875,6 +2879,10 @@
// A name identifying this isolate. Not guaranteed to be unique.
string name;
+ // Specifies whether the isolate was spawned by the VM or embedder for
+ // internal use. If `false`, this isolate is likely running user code.
+ bool isSystemIsolate;
+
// The time that the VM started in milliseconds since the epoch.
//
// Suitable to pass to DateTime.fromMillisecondsSinceEpoch.
@@ -2932,6 +2940,10 @@
// A name identifying this isolate group. Not guaranteed to be unique.
string name;
+
+ // Specifies whether the isolate group was spawned by the VM or embedder for
+ // internal use. If `false`, this isolate group is likely running user code.
+ bool isSystemIsolateGroup;
}
```
@@ -2949,6 +2961,10 @@
// A name identifying this isolate. Not guaranteed to be unique.
string name;
+ // Specifies whether the isolate group was spawned by the VM or embedder for
+ // internal use. If `false`, this isolate group is likely running user code.
+ bool isSystemIsolateGroup;
+
// A list of all isolates in this isolate group.
@Isolate[] isolates;
}
@@ -3862,6 +3878,12 @@
// A list of isolate groups running in the VM.
@IsolateGroup[] isolateGroups;
+
+ // A list of system isolates running in the VM.
+ @Isolate[] systemIsolates;
+
+ // A list of isolate groups which contain system isolates running in the VM.
+ @IsolateGroup[] systemIsolateGroups;
}
```
@@ -3921,5 +3943,7 @@
3.35 | Added `getSupportedProtocols` RPC and `ProtocolList`, `Protocol` objects.
3.36 | Added `getProcessMemoryUsage` RPC and `ProcessMemoryUsage` and `ProcessMemoryItem` objects.
3.37 | Added `getWebSocketTarget` RPC and `WebSocketTarget` object.
+3.38 | Added `isSystemIsolate` property to `@Isolate` and `Isolate`, `isSystemIsolateGroup` property to `@IsolateGroup` and `IsolateGroup`,
+and properties `systemIsolates` and `systemIsolateGroups` to `VM`.
[discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss
diff --git a/runtime/vm/service_event.cc b/runtime/vm/service_event.cc
index 26cc103..5b90440 100644
--- a/runtime/vm/service_event.cc
+++ b/runtime/vm/service_event.cc
@@ -36,8 +36,9 @@
timestamp_(OS::GetCurrentTimeMillis()) {
// We should never generate events for the vm or service isolates.
ASSERT(isolate_ != Dart::vm_isolate());
- ASSERT(isolate == NULL || FLAG_show_invisible_isolates ||
- !Isolate::IsVMInternalIsolate(isolate));
+ ASSERT(isolate == NULL || !Isolate::IsSystemIsolate(isolate) ||
+ (Isolate::IsSystemIsolate(isolate) &&
+ event_kind == ServiceEvent::kResume));
if ((event_kind == ServiceEvent::kPauseStart) ||
(event_kind == ServiceEvent::kPauseExit)) {
diff --git a/runtime/vm/service_isolate.cc b/runtime/vm/service_isolate.cc
index 068d478..f785a65 100644
--- a/runtime/vm/service_isolate.cc
+++ b/runtime/vm/service_isolate.cc
@@ -213,7 +213,7 @@
}
Thread* thread = Thread::Current();
Isolate* isolate = thread->isolate();
- if (!FLAG_show_invisible_isolates && Isolate::IsVMInternalIsolate(isolate)) {
+ if (Dart::VmIsolateNameEquals(isolate->name())) {
return false;
}
ASSERT(isolate != NULL);
@@ -239,7 +239,7 @@
}
Thread* thread = Thread::Current();
Isolate* isolate = thread->isolate();
- if (!FLAG_show_invisible_isolates && Isolate::IsVMInternalIsolate(isolate)) {
+ if (Dart::VmIsolateNameEquals(isolate->name())) {
return false;
}
ASSERT(isolate != NULL);
@@ -351,7 +351,7 @@
Dart_IsolateFlags api_flags;
Isolate::FlagsInitialize(&api_flags);
-
+ api_flags.is_system_isolate = true;
isolate = reinterpret_cast<Isolate*>(
create_group_callback(ServiceIsolate::kName, ServiceIsolate::kName,
NULL, NULL, &api_flags, NULL, &error));
@@ -586,6 +586,44 @@
ServiceIsolate::SetServicePort(port);
}
+void ServiceIsolate::RegisterRunningIsolate(Isolate* isolate) {
+ ASSERT(ServiceIsolate::IsServiceIsolate(Isolate::Current()));
+
+ // Get library.
+ const String& library_url = Symbols::DartVMService();
+ ASSERT(!library_url.IsNull());
+ // TODO(bkonyi): hoist Thread::Current()
+ const Library& library =
+ Library::Handle(Library::LookupLibrary(Thread::Current(), library_url));
+ ASSERT(!library.IsNull());
+ // Get function.
+ const String& function_name = String::Handle(String::New("_registerIsolate"));
+ ASSERT(!function_name.IsNull());
+ const Function& register_function_ =
+ Function::Handle(library.LookupFunctionAllowPrivate(function_name));
+ ASSERT(!register_function_.IsNull());
+
+ // Setup arguments for call.
+ Dart_Port port_id = isolate->main_port();
+ const Integer& port_int = Integer::Handle(Integer::New(port_id));
+ ASSERT(!port_int.IsNull());
+ const SendPort& send_port = SendPort::Handle(SendPort::New(port_id));
+ const String& name = String::Handle(String::New(isolate->name()));
+ ASSERT(!name.IsNull());
+ const Array& args = Array::Handle(Array::New(3));
+ ASSERT(!args.IsNull());
+ args.SetAt(0, port_int);
+ args.SetAt(1, send_port);
+ args.SetAt(2, name);
+ const Object& r =
+ Object::Handle(DartEntry::InvokeFunction(register_function_, args));
+ if (FLAG_trace_service) {
+ OS::PrintErr("vm-service: Isolate %s %" Pd64 " registered.\n",
+ name.ToCString(), port_id);
+ }
+ ASSERT(!r.IsError());
+}
+
void ServiceIsolate::VisitObjectPointers(ObjectPointerVisitor* visitor) {}
} // namespace dart
diff --git a/runtime/vm/service_isolate.h b/runtime/vm/service_isolate.h
index 44cbd78..5411bb9 100644
--- a/runtime/vm/service_isolate.h
+++ b/runtime/vm/service_isolate.h
@@ -50,6 +50,8 @@
static void BootVmServiceLibrary();
+ static void RegisterRunningIsolate(Isolate* isolate);
+
static void RequestServerInfo(const SendPort& sp);
static void ControlWebServer(const SendPort& sp,
bool enable,
@@ -106,6 +108,7 @@
static bool SendIsolateShutdownMessage() { return false; }
static void SendServiceExitMessage() {}
static void Shutdown() {}
+ static void RegisterRunningIsolate(Isolate* isolate) {}
static void VisitObjectPointers(ObjectPointerVisitor* visitor) {}
protected:
diff --git a/sdk/lib/_http/http_headers.dart b/sdk/lib/_http/http_headers.dart
index 73ed901..7d87b88 100644
--- a/sdk/lib/_http/http_headers.dart
+++ b/sdk/lib/_http/http_headers.dart
@@ -913,7 +913,7 @@
DateTime? expires;
int? maxAge;
String? domain;
- String? path;
+ String? _path;
bool httpOnly = false;
bool secure = false;
@@ -925,6 +925,13 @@
String get name => _name;
String get value => _value;
+ String? get path => _path;
+
+ set path(String? newPath) {
+ _validatePath(newPath);
+ _path = newPath;
+ }
+
set name(String newName) {
_validateName(newName);
_name = newName;
@@ -1104,4 +1111,19 @@
}
return newValue;
}
+
+ static void _validatePath(String? path) {
+ if (path == null) return;
+ for (int i = 0; i < path.length; i++) {
+ int codeUnit = path.codeUnitAt(i);
+ // According to RFC 6265, semicolon and controls should not occur in the
+ // path.
+ // path-value = <any CHAR except CTLs or ";">
+ // CTLs = %x00-1F / %x7F
+ if (codeUnit < 0x20 || codeUnit >= 0x7f || codeUnit == 0x3b /*;*/) {
+ throw FormatException(
+ "Invalid character in cookie path, code unit: '$codeUnit'");
+ }
+ }
+ }
}
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index b0ee0ae..76ced6e 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -2345,7 +2345,7 @@
* still pending delivery, if the subscription is paused,
* or if the subscription isn't listening yet.
* If it's necessary to know whether the "done" event has been delievered,
- * [done] future will complete when that has happend.
+ * [done] future will complete when that has happened.
*/
void closeSync();
}
diff --git a/tests/language/nnbd/definite_assignment/write_error_test.dart b/tests/language/nnbd/definite_assignment/write_error_test.dart
index 81d27b6..4c6c00e 100644
--- a/tests/language/nnbd/definite_assignment/write_error_test.dart
+++ b/tests/language/nnbd/definite_assignment/write_error_test.dart
@@ -17,7 +17,7 @@
/// Test that it is never an error to write to a definitely unassigned local
/// variable.
-void testDefinitelyUnassignedWrites<T>() {
+void testDefinitelyUnassignedWrites<T>(T t) {
{
var x;
x = 3;
diff --git a/tests/standalone/io/http_cookie_test.dart b/tests/standalone/io/http_cookie_test.dart
index bfe9302..5aa1cf9 100644
--- a/tests/standalone/io/http_cookie_test.dart
+++ b/tests/standalone/io/http_cookie_test.dart
@@ -83,7 +83,35 @@
() => Cookie.fromSetCookieValue('key="x""; HttpOnly'));
}
+void testValidatePath() {
+ Cookie cookie = Cookie.fromSetCookieValue(" cname = cval; path= / ");
+ Expect.equals('/', cookie.path);
+ cookie.path = null;
+ Expect.throws<FormatException>(() {
+ cookie.path = "something; ";
+ }, (e) => e.toString().contains('Invalid character'));
+
+ StringBuffer buffer = StringBuffer();
+ buffer.writeCharCode(0x1f);
+ Expect.throws<FormatException>(() {
+ cookie.path = buffer.toString();
+ }, (e) => e.toString().contains('Invalid character'));
+
+ buffer.clear();
+ buffer.writeCharCode(0x7f);
+ Expect.throws<FormatException>(() {
+ cookie.path = buffer.toString();
+ }, (e) => e.toString().contains('Invalid character'));
+
+ buffer.clear();
+ buffer.writeCharCode(0x00);
+ Expect.throws<FormatException>(() {
+ cookie.path = buffer.toString();
+ }, (e) => e.toString().contains('Invalid character'));
+}
+
void main() {
testCookies();
testValidateCookieWithDoubleQuotes();
+ testValidatePath();
}
diff --git a/tests/standalone_2/io/http_cookie_test.dart b/tests/standalone_2/io/http_cookie_test.dart
index bfe9302..5aa1cf9 100644
--- a/tests/standalone_2/io/http_cookie_test.dart
+++ b/tests/standalone_2/io/http_cookie_test.dart
@@ -83,7 +83,35 @@
() => Cookie.fromSetCookieValue('key="x""; HttpOnly'));
}
+void testValidatePath() {
+ Cookie cookie = Cookie.fromSetCookieValue(" cname = cval; path= / ");
+ Expect.equals('/', cookie.path);
+ cookie.path = null;
+ Expect.throws<FormatException>(() {
+ cookie.path = "something; ";
+ }, (e) => e.toString().contains('Invalid character'));
+
+ StringBuffer buffer = StringBuffer();
+ buffer.writeCharCode(0x1f);
+ Expect.throws<FormatException>(() {
+ cookie.path = buffer.toString();
+ }, (e) => e.toString().contains('Invalid character'));
+
+ buffer.clear();
+ buffer.writeCharCode(0x7f);
+ Expect.throws<FormatException>(() {
+ cookie.path = buffer.toString();
+ }, (e) => e.toString().contains('Invalid character'));
+
+ buffer.clear();
+ buffer.writeCharCode(0x00);
+ Expect.throws<FormatException>(() {
+ cookie.path = buffer.toString();
+ }, (e) => e.toString().contains('Invalid character'));
+}
+
void main() {
testCookies();
testValidateCookieWithDoubleQuotes();
+ testValidatePath();
}
diff --git a/tools/VERSION b/tools/VERSION
index 3392be0..f0b5f4b 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 10
PATCH 0
-PRERELEASE 51
+PRERELEASE 52
PRERELEASE_PATCH 0
\ No newline at end of file