Skip to content

Instantly share code, notes, and snippets.

@lrhn
Last active July 16, 2018 06:01
Show Gist options
  • Save lrhn/35c9947fff55896252155463199429dd to your computer and use it in GitHub Desktop.
Save lrhn/35c9947fff55896252155463199429dd to your computer and use it in GitHub Desktop.
import "dart:io";
bool verbose = false;
bool dryRun = false;
main(List<String> args) {
int unchanged = 0;
for(var path in args) {
if (path == "-v") {
verbose = true;
continue;
}
if (path == "-n") {
dryRun = true;
continue;
}
var file = new File(path);
if (file.existsSync()) {
String content;
try {
content = file.readAsStringSync();
} catch (e) {
stderr.writeln("$path: cannot be read!");
continue;
}
String newContent = fixConstants(content);
if (newContent != content) {
try {
if (!dryRun) file.writeAsStringSync(newContent);
} catch (e, s) {
stderr.writeln("$path: cannot be written!\n$e\n$s");
continue;
}
stderr.writeln("$path: updated");
} else {
unchanged++;
if (verbose) stderr.writeln("$path: unchanged");
}
} else {
stderr.writeln("$path: not found!");
}
}
if (unchanged > 0) stderr.writeln("Unchanged files: $unchanged");
}
var screamingCapsPattern = new RegExp(r"\b[A-Z][A-Z\d]*(?:_[A-Z\d]+)*\b");
String screamingToCamel(String screaming) {
var result = constantMapping[screaming];
if (result == null) {
var parts = screaming.split("_").toList();
parts[0] = parts[0].toLowerCase();
for (int i = 1; i < parts.length; i++) {
var part = parts[i];
parts[i] = part[0] + part.substring(1).toLowerCase();
}
result = constantMapping[screaming] = parts.join("");
}
return result;
}
var wsRE = new RegExp(r"\s+");
String toCamelCase(String text) {
text = text.replaceAll(wsRE, "");
var result = constantMapping[text] ??=
text.replaceAllMapped(screamingCapsPattern, (m) => screamingToCamel(m[0]));
return result;
}
// Cached translations, seeded with those that don't follow the standard
// SCREAMING_CAPS -> screamingCaps conversion.
var constantMapping = {
"Endianness": "Endian",
"Endianness.BIG_ENDIAN": "Endian.big",
"Endianness.LITTLE_ENDIAN": "Endian.little",
"Endianness.HOST_ENDIAN": "Endian.host",
"JSON.encode": "jsonEncode",
"JSON.decode": "jsonDecode",
"BASE64.encode": "base64Encode",
"BASE64.decode": "base64Decode",
"BASE64URL": "base64Url",
"BASE64URL.decode": "base64Url.decode",
"BASE64URL.decoder": "base64Url.decoder",
"BASE64URL.encode": "base64Url.encode",
"BASE64URL.encoder": "base64Url.encoder",
"BASE64URL.fuse": "base64Url.fuse",
"BASE64URL.inverted": "base64Url.inverted",
"JsonEncoder.DEFAULT_BUFFER_SIZE": "256",
"SQRT1_2": "sqrt1_2",
"HttpStatus.CONTINUE": "HttpStatus.continue_",
"Httpheaders.ACCEPT": "HttpHeaders.acceptHeader",
"Httpheaders.ACCEPT_CHARSET": "HttpHeaders.acceptCharsetHeader",
"Httpheaders.ACCEPT_ENCODING": "HttpHeaders.acceptEncodingHeader",
"Httpheaders.ACCEPT_LANGUAGE": "HttpHeaders.acceptLanguageHeader",
"Httpheaders.ACCEPT_RANGES": "HttpHeaders.acceptRangesHeader",
"Httpheaders.AGE": "HttpHeaders.ageHeader",
"Httpheaders.ALLOW": "HttpHeaders.allowHeader",
"Httpheaders.AUTHORIZATION": "HttpHeaders.authorizationHeader",
"Httpheaders.CACHE_CONTROL": "HttpHeaders.cacheControlHeader",
"Httpheaders.CONNECTION": "HttpHeaders.connectionHeader",
"Httpheaders.CONTENT_ENCODING": "HttpHeaders.contentEncodingHeader",
"Httpheaders.CONTENT_LANGUAGE": "HttpHeaders.contentLanguageHeader",
"Httpheaders.CONTENT_LENGTH": "HttpHeaders.contentLengthHeader",
"Httpheaders.CONTENT_LOCATION": "HttpHeaders.contentLocationHeader",
"Httpheaders.CONTENT_MD5": "HttpHeaders.contentMD5Header",
"Httpheaders.CONTENT_RANGE": "HttpHeaders.contentRangeHeader",
"Httpheaders.CONTENT_TYPE": "HttpHeaders.contentTypeHeader",
"Httpheaders.DATE": "HttpHeaders.dateHeader",
"Httpheaders.ETAG": "HttpHeaders.etagHeader",
"Httpheaders.EXPECT": "HttpHeaders.expectHeader",
"Httpheaders.EXPIRES": "HttpHeaders.expiresHeader",
"Httpheaders.FROM": "HttpHeaders.fromHeader",
"Httpheaders.HOST": "HttpHeaders.hostHeader",
"Httpheaders.IF_MATCH": "HttpHeaders.ifMatchHeader",
"Httpheaders.IF_MODIFIED_SINCE": "HttpHeaders.ifModifiedSinceHeader",
"Httpheaders.IF_NONE_MATCH": "HttpHeaders.ifNoneMatchHeader",
"Httpheaders.IF_RANGE": "HttpHeaders.ifRangeHeader",
"Httpheaders.IF_UNMODIFIED_SINCE": "HttpHeaders.ifUnmodifiedSinceHeader",
"Httpheaders.LAST_MODIFIED": "HttpHeaders.lastModifiedHeader",
"Httpheaders.LOCATION": "HttpHeaders.locationHeader",
"Httpheaders.MAX_FORWARDS": "HttpHeaders.maxForwardsHeader",
"Httpheaders.PRAGMA": "HttpHeaders.pragmaHeader",
"Httpheaders.PROXY_AUTHENTICATE": "HttpHeaders.proxyAuthenticateHeader",
"Httpheaders.PROXY_AUTHORIZATION": "HttpHeaders.proxyAuthorizationHeader",
"Httpheaders.RANGE": "HttpHeaders.rangeHeader",
"Httpheaders.REFERER": "HttpHeaders.refererHeader",
"Httpheaders.RETRY_AFTER": "HttpHeaders.retryAfterHeader",
"Httpheaders.SERVER": "HttpHeaders.serverHeader",
"Httpheaders.TE": "HttpHeaders.teHeader",
"Httpheaders.TRAILER": "HttpHeaders.trailerHeader",
"Httpheaders.TRANSFER_ENCODING": "HttpHeaders.transferEncodingHeader",
"Httpheaders.UPGRADE": "HttpHeaders.upgradeHeader",
"Httpheaders.USER_AGENT": "HttpHeaders.userAgentHeader",
"Httpheaders.VARY": "HttpHeaders.varyHeader",
"Httpheaders.VIA": "HttpHeaders.viaHeader",
"Httpheaders.WARNING": "HttpHeaders.warningHeader",
"Httpheaders.WWW_AUTHENTICATE": "HttpHeaders.wwwAuthenticateHeader",
"Httpheaders.COOKIE": "HttpHeaders.cookieHeader",
"Httpheaders.SET_COOKIE": "HttpHeaders.setCookieHeader",
"InternetAddress.LOOPBACK_IP_V4": "InternetAddress.loopbackIPv4",
"InternetAddress.LOOPBACK_IP_V6": "InternetAddress.loopbackIPv6",
"InternetAddress.ANY_IP_V4": "InternetAddress.anyIPv4",
"InternetAddress.ANY_IP_V6": "InternetAddress.anyIPv6",
};
// Pattern recognizing references to upper-case constant names.
var changePattern = new RegExp(
r"(//.*"
r"|/\*(?:[^*]|\*(?!/))*\*/"
r"|r'[^'\n]*'"
r'|r"[^"\n]*"'
r"|'(?:[^'$\n]|\$(?!\{))*'"
r'|"(?:[^"$\n]|\$(?!\{))*")'
r"|\b(?:JSON|BASE64(?:URL)?)\s*\.(?:decoder?|encoder?|fuse|inverted)\b"
r"|\b(?:UTF8|ASCII|LATIN1|HTML_ESCAPE)\b"
r"|\bJsonEncoder\.DEFAULT_BUFFER_SIZE\b"
r"|\bZone\.ROOT\b"
r"|\bHtmlEscapeMode\.(?:UNKNOWN|ATTRIBUTE|SQ_ATTRIBUTE|ELEMENT)\b"
r"|\bDateTime\.(?:MONDAY|TUESDAY|WEDNESDAY|THURSDAY|FRIDAY|SATURDAY|"
r"SUNDAY|DAYS_PER_WEEK|JANUARY|FEBRUARY|MARCH|APRIL|MAY|JUNE|JULY|"
r"AUGUST|SEPTEMBER|OCTOBER|NOVEMBER|DECEMBER|MONTHS_PER_YEAR)\b"
r"|\bdouble\.(?:NAN|INFINITY|NEGATIVE_INFINITY|MIN_POSITIVE|MAX_FINITE)\b"
r"|\bDuration\.(?:MICROSECONDS_PER_MILLISECOND|MILLISECONDS_PER_SECOND|"
r"SECONDS_PER_MINUTE|MINUTES_PER_HOUR|HOURS_PER_DAY|MICROSECONDS_PER_SECOND|"
r"MICROSECONDS_PER_MINUTE|MICROSECONDS_PER_HOUR|MICROSECONDS_PER_DAY|"
r"MILLISECONDS_PER_MINUTE|MILLISECONDS_PER_HOUR|MILLISECONDS_PER_DAY|"
r"SECONDS_PER_HOUR|SECONDS_PER_DAY|MINUTES_PER_DAY|ZERO)\b"
r"|\bEndianness(?:\.(?:BIG|LITTLE|HOST)_ENDIAN)?\b"
r"|\bIsolate\.(?:IMMEDIATE|BEFORE_NEXT_EVENT)\b"
r"|\b(?:LN(?:2|10)|LOG(?:2|10)E|PI|SQRT(?:2|1_2))\b"
r"|\b(?:Uint|Int|Float)(?:8|16|32|64)(?:x[24])?List\.BYTES_PER_ELEMENT\b"
r"|\b(?:Int|Float)32x4\.[XYZW]{4}\b"
r"|\b(?:Http(?:Status|Headers)|ZLibOption|"
r"File(?:Mode|Lock|System(?:EntityType|Event))|Process(?:StartMode|Signal)|StdioType)\.[A-Z_]{2,}\b"
r"|\bContentType\.(?:TEXT|HTML|JSON|BINARY)\b"
r"|\bInternetAddress\.(?:ANY|LOOPBACK)_IP_V[46]\b"
r"|\bSYSTEM_ENCODING\b"
);
// Pattern recognizing upper-case constants in import-show declarations.
// Heuristics based what it needs to contain.
var showPattern =
new RegExp(r"^(\b(?:import|export)\b[^;]*\bshow\b[^;]*\b)"
r"(JSON|ASCII|LATIN1|BASE64(?:URL)?|UTF8)\b");
var jsonUsageRE = new RegExp(r"\bJSON\b\s*(?:\.(en|de)code\b)?");
var base64UsageRE = new RegExp(r"\bBASE64\b\s*(?:\.(en|de)code\b)?");
String fixConstants(String content) {
var newContent = content;
Set<String> jsonReplacement = null;
Set<String> base64Replacement = null;
do {
content = newContent;
newContent = content.replaceAllMapped(showPattern, (m) {
var replacement ;
if (m[2] == "JSON") {
jsonReplacement = new Set();
replacement = "!~!json!~!";
} else if (m[2] == "BASE64") {
base64Replacement = new Set();
replacement = "!~!base64!~!";
} else {
replacement = toCamelCase(m[2]);
}
return m[1] + replacement;
});
} while (newContent != content);
newContent = newContent.replaceAllMapped(changePattern, (m) {
//print("--${m[0]}");
if (m[1] != null) {
return m[0];
}
var replacement = toCamelCase(m[0]);
if (jsonReplacement != null &&
(replacement == "json" || replacement == "jsonEncode" || replacement == "jsonDecode")) {
jsonReplacement.add(replacement);
}
if (base64Replacement != null &&
(replacement == "base64" || replacement == "base64Encode" || replacement == "base64Decode")) {
base64Replacement.add(replacement);
}
return replacement;
});
if (jsonReplacement != null) {
newContent = newContent.replaceFirst("!~!json!~!", (jsonReplacement.toList()..sort()).join(", "));
}
if (base64Replacement != null) {
newContent = newContent.replaceFirst("!~!base64!~!", (base64Replacement.toList()..sort()).join(", "));
}
return newContent;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment