Last active
July 16, 2018 06:01
-
-
Save lrhn/35c9947fff55896252155463199429dd to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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