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

Unified Diff: pkg/analyzer/lib/src/dart/sdk/patch.dart

Issue 2616993002: Reject patches that change parameter names/types or return types. (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | pkg/analyzer/test/src/dart/sdk/patch_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analyzer/lib/src/dart/sdk/patch.dart
diff --git a/pkg/analyzer/lib/src/dart/sdk/patch.dart b/pkg/analyzer/lib/src/dart/sdk/patch.dart
index 60ac49d2ac31494671ce00e11c0baedbff2795a4..44f6765ddfc3be2fcfa0f36977d6bb8868cac162 100644
--- a/pkg/analyzer/lib/src/dart/sdk/patch.dart
+++ b/pkg/analyzer/lib/src/dart/sdk/patch.dart
@@ -99,6 +99,78 @@ class SdkPatcher {
return 'the line ${location.lineNumber}';
}
+ void _matchParameterLists(FormalParameterList baseParameters,
+ FormalParameterList patchParameters, String context()) {
+ if (baseParameters == null && patchParameters == null) return;
+ if (baseParameters == null || patchParameters == null) {
+ throw new ArgumentError("${context()}, parameter lists don't match");
+ }
+ if (baseParameters.parameters.length != patchParameters.parameters.length) {
+ throw new ArgumentError(
+ '${context()}, parameter lists have different lengths');
+ }
+ for (var i = 0; i < baseParameters.parameters.length; i++) {
+ _matchParameters(baseParameters.parameters[i],
+ patchParameters.parameters[i], () => '${context()}, parameter $i');
+ }
+ }
+
+ void _matchParameters(FormalParameter baseParameter,
+ FormalParameter patchParameter, String whichParameter()) {
+ if (baseParameter.identifier.name != patchParameter.identifier.name) {
+ throw new ArgumentError('${whichParameter()} has different name');
+ }
+ NormalFormalParameter baseParameterWithoutDefault =
+ _withoutDefault(baseParameter);
+ NormalFormalParameter patchParameterWithoutDefault =
+ _withoutDefault(patchParameter);
+ if (baseParameterWithoutDefault is SimpleFormalParameter &&
+ patchParameterWithoutDefault is SimpleFormalParameter) {
+ _matchTypes(baseParameterWithoutDefault.type,
+ patchParameterWithoutDefault.type, () => '${whichParameter()} type');
+ } else if (baseParameterWithoutDefault is FunctionTypedFormalParameter &&
+ patchParameterWithoutDefault is FunctionTypedFormalParameter) {
+ _matchTypes(
+ baseParameterWithoutDefault.returnType,
+ patchParameterWithoutDefault.returnType,
+ () => '${whichParameter()} return type');
+ _matchParameterLists(
+ baseParameterWithoutDefault.parameters,
+ patchParameterWithoutDefault.parameters,
+ () => '${whichParameter()} parameters');
+ } else if (baseParameterWithoutDefault is FieldFormalParameter &&
+ patchParameter is FieldFormalParameter) {
+ throw new ArgumentError(
+ '${whichParameter()} cannot be patched (field formal parameters are not supported)');
+ } else {
+ throw new ArgumentError(
+ '${whichParameter()} mismatch (different parameter kinds)');
+ }
+ }
+
+ void _matchTypes(TypeName baseType, TypeName patchType, String whichType()) {
+ error() => new ArgumentError("${whichType()} doesn't match");
+ if (baseType == null && patchType == null) return;
+ if (baseType == null || patchType == null) throw error();
+ // Match up the types token by token; this is more restrictive than strictly
+ // necessary, but it's easy and sufficient for patching purposes.
+ Token baseToken = baseType.beginToken;
+ Token patchToken = patchType.beginToken;
+ while (true) {
+ if (baseToken.lexeme != patchToken.lexeme) throw error();
+ if (identical(baseToken, baseType.endToken) &&
+ identical(patchToken, patchType.endToken)) {
+ break;
+ }
+ if (identical(baseToken, baseType.endToken) ||
+ identical(patchToken, patchType.endToken)) {
+ throw error();
+ }
+ baseToken = baseToken.next;
+ patchToken = patchToken.next;
+ }
+ }
+
void _patchClassMembers(
ClassDeclaration baseClass, ClassDeclaration patchClass) {
String className = baseClass.name.name;
@@ -134,6 +206,12 @@ class SdkPatcher {
} else {
_failExternalKeyword(name, baseMember.offset);
}
+ _matchParameterLists(
+ baseMember.parameters,
+ patchMember.parameters,
+ () => 'While patching $className.$name');
+ _matchTypes(baseMember.returnType, patchMember.returnType,
+ () => 'While patching $className.$name, return type');
// Replace the body.
FunctionBody oldBody = baseMember.body;
FunctionBody newBody = patchMember.body;
@@ -177,6 +255,11 @@ class SdkPatcher {
'Cannot patch external constructors with initializers '
'in $_baseDesc.');
}
+ _matchParameterLists(
+ baseMember.parameters, patchMember.parameters, () {
+ String nameSuffix = name == null ? '' : '.$name';
+ return 'While patching $className$nameSuffix';
+ });
// Prepare nodes.
FunctionBody baseBody = baseMember.body;
FunctionBody patchBody = patchMember.body;
@@ -250,6 +333,14 @@ class SdkPatcher {
} else {
_failExternalKeyword(name, baseDeclaration.offset);
}
+ _matchParameterLists(
+ baseDeclaration.functionExpression.parameters,
+ patchDeclaration.functionExpression.parameters,
+ () => 'While patching $name');
+ _matchTypes(
+ baseDeclaration.returnType,
+ patchDeclaration.returnType,
+ () => 'While patching $name, return type');
// Replace the body.
FunctionExpression oldExpr = baseDeclaration.functionExpression;
FunctionBody newBody = patchDeclaration.functionExpression.body;
@@ -300,6 +391,18 @@ class SdkPatcher {
}
}
+ NormalFormalParameter _withoutDefault(FormalParameter parameter) {
+ if (parameter is NormalFormalParameter) {
+ return parameter;
+ } else if (parameter is DefaultFormalParameter) {
+ return parameter.parameter;
+ } else {
+ // Should not happen.
+ assert(false);
+ return null;
+ }
+ }
+
/**
* Parse the given [source] into AST.
*/
« no previous file with comments | « no previous file | pkg/analyzer/test/src/dart/sdk/patch_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698