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

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

Issue 2412453007: Add support for patching class methods. (Closed)
Patch Set: Created 4 years, 2 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 576cb96149b00c6e687877b6bb316b0cf38d9cd7..f2bfeb30cb8643607a550a3506f5dabb95d4e898 100644
--- a/pkg/analyzer/lib/src/dart/sdk/patch.dart
+++ b/pkg/analyzer/lib/src/dart/sdk/patch.dart
@@ -72,14 +72,13 @@ class SdkPatcher {
_patchDirectives(
source, unit, patchSource, patchUnit, addNewTopLevelDeclarations);
- _patchTopLevelDeclarations(
- source, unit, patchSource, patchUnit, addNewTopLevelDeclarations);
+ _patchTopLevelDeclarations(unit, patchUnit, addNewTopLevelDeclarations);
}
}
- void _failExternalKeyword(Source source, String name, int offset) {
+ void _failExternalKeyword(String name, int offset) {
throw new ArgumentError(
- 'The keyword "external" was expected for "$name" in $source @ $offset.');
+ 'The keyword "external" was expected for "$name" in $_baseDesc @ $offset.');
}
void _failIfPublicName(AstNode node, String name) {
@@ -99,6 +98,53 @@ class SdkPatcher {
return 'the line ${location.lineNumber}';
}
+ void _patchClassMembers(
+ ClassDeclaration baseClass, ClassDeclaration patchClass) {
+ List<ClassMember> membersToAppend = [];
+ for (ClassMember patchMember in patchClass.members) {
+ if (patchMember is MethodDeclaration) {
+ String name = patchMember.name.name;
+ if (_hasPatchAnnotation(patchMember.metadata)) {
+ for (ClassMember baseMember in baseClass.members) {
+ if (baseMember is MethodDeclaration &&
+ baseMember.name.name == name) {
+ // Remove the "external" keyword.
Paul Berry 2016/10/13 19:09:52 It looks like we have some duplication between thi
scheglov 2016/10/13 20:18:14 It does not seem practical to me. Both "externalKe
+ Token externalKeyword = baseMember.externalKeyword;
+ if (externalKeyword != null) {
+ baseMember.externalKeyword = null;
+ _removeToken(externalKeyword);
+ } else {
+ _failExternalKeyword(name, baseMember.offset);
+ }
+ // Replace the body.
+ FunctionBody oldBody = baseMember.body;
+ FunctionBody newBody = patchMember.body;
+ _replaceNodeTokens(oldBody, newBody);
+ baseMember.body = newBody;
+ }
+ }
+ } else {
+ _failIfPublicName(patchMember, name);
+ membersToAppend.add(patchMember);
+ }
+ } else {
+ // TODO(scheglov) support field
+ // TODO(scheglov) support constructors
+ String className = patchClass.name.name;
+ _failInPatch('contains an unsupported class member in $className',
+ patchMember.offset);
+ }
+ }
+ // Append new top-level declarations.
+ Token lastToken = baseClass.endToken.previous;
+ for (ClassMember newMember in membersToAppend) {
+ newMember.endToken.setNext(lastToken.next);
Paul Berry 2016/10/13 19:09:52 Consider extracting a method for this logic too.
scheglov 2016/10/13 20:18:14 OK https://codereview.chromium.org/2417053002
+ lastToken.setNext(newMember.beginToken);
+ baseClass.members.add(newMember);
+ lastToken = newMember.endToken;
+ }
+ }
+
void _patchDirectives(
Source baseSource,
CompilationUnit baseUnit,
@@ -115,12 +161,8 @@ class SdkPatcher {
}
}
- void _patchTopLevelDeclarations(
- Source baseSource,
- CompilationUnit baseUnit,
- Source patchSource,
- CompilationUnit patchUnit,
- bool addNewTopLevelDeclarations) {
+ void _patchTopLevelDeclarations(CompilationUnit baseUnit,
+ CompilationUnit patchUnit, bool addNewTopLevelDeclarations) {
List<CompilationUnitMember> declarationsToAppend = [];
for (CompilationUnitMember patchDeclaration in patchUnit.declarations) {
if (patchDeclaration is FunctionDeclaration) {
@@ -130,22 +172,19 @@ class SdkPatcher {
if (patchDeclaration is FunctionDeclaration &&
baseDeclaration is FunctionDeclaration &&
baseDeclaration.name.name == name) {
- if (_hasPatchAnnotation(patchDeclaration.metadata)) {
- // Remove the "external" keyword.
- Token externalKeyword = baseDeclaration.externalKeyword;
- if (externalKeyword != null) {
- baseDeclaration.externalKeyword = null;
- _removeToken(externalKeyword);
- } else {
- _failExternalKeyword(
- baseSource, name, baseDeclaration.offset);
- }
- // Replace the body.
- FunctionExpression oldExpr = baseDeclaration.functionExpression;
- FunctionBody newBody = patchDeclaration.functionExpression.body;
- _replaceNodeTokens(oldExpr.body, newBody);
- oldExpr.body = newBody;
+ // Remove the "external" keyword.
+ Token externalKeyword = baseDeclaration.externalKeyword;
+ if (externalKeyword != null) {
+ baseDeclaration.externalKeyword = null;
+ _removeToken(externalKeyword);
+ } else {
+ _failExternalKeyword(name, baseDeclaration.offset);
}
+ // Replace the body.
+ FunctionExpression oldExpr = baseDeclaration.functionExpression;
+ FunctionBody newBody = patchDeclaration.functionExpression.body;
+ _replaceNodeTokens(oldExpr.body, newBody);
+ oldExpr.body = newBody;
}
}
} else if (addNewTopLevelDeclarations) {
@@ -159,6 +198,19 @@ class SdkPatcher {
}
_failIfPublicName(patchDeclaration, patchDeclaration.name.name);
declarationsToAppend.add(patchDeclaration);
+ } else if (patchDeclaration is ClassDeclaration) {
+ if (_hasPatchAnnotation(patchDeclaration.metadata)) {
+ String name = patchDeclaration.name.name;
+ for (CompilationUnitMember baseDeclaration in baseUnit.declarations) {
+ if (baseDeclaration is ClassDeclaration &&
+ baseDeclaration.name.name == name) {
+ _patchClassMembers(baseDeclaration, patchDeclaration);
+ }
+ }
+ } else {
+ _failIfPublicName(patchDeclaration, patchDeclaration.name.name);
+ declarationsToAppend.add(patchDeclaration);
+ }
} else {
_failInPatch('contains an unsupported top-level declaration',
patchDeclaration.offset);
« 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