Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of dart_backend; | 5 part of dart_backend; |
| 6 | 6 |
| 7 Comparator get _compareNodes => | 7 Comparator get _compareNodes => |
| 8 compareBy((n) => n.getBeginToken().charOffset); | 8 compareBy((n) => n.getBeginToken().charOffset); |
| 9 | 9 |
| 10 typedef String _Renamer(Renamable renamable); | 10 typedef String _NameGenerator(String original); |
| 11 | 11 |
| 12 abstract class Renamable { | 12 abstract class Renamable implements Comparable { |
| 13 final int RENAMABLE_TYPE_ELEMENT = 1; | 13 final int RENAMABLE_TYPE_ELEMENT = 1; |
| 14 final int RENAMABLE_TYPE_MEMBER = 2; | 14 final int RENAMABLE_TYPE_MEMBER = 2; |
| 15 final int RENAMABLE_TYPE_LOCAL = 3; | 15 final int RENAMABLE_TYPE_LOCAL = 3; |
| 16 | 16 |
| 17 final Set<Node> nodes; | 17 final Set<Node> nodes; |
| 18 final _Renamer renamer; | 18 |
| 19 | 19 Renamable(this.nodes); |
| 20 Renamable(this.nodes, this.renamer); | |
| 21 int compareTo(Renamable other) { | 20 int compareTo(Renamable other) { |
| 22 int nodesDiff = other.nodes.length.compareTo(this.nodes.length); | 21 int nodesDiff = other.nodes.length.compareTo(this.nodes.length); |
| 23 if (nodesDiff != 0) return nodesDiff; | 22 if (nodesDiff != 0) return nodesDiff; |
| 24 int typeDiff = this.getTypeId().compareTo(other.getTypeId()); | 23 int typeDiff = this.kind.compareTo(other.kind); |
| 25 return typeDiff != 0 ? typeDiff : compareInternals(other); | 24 return typeDiff != 0 ? typeDiff : compareInternals(other); |
| 26 } | 25 } |
| 27 | 26 |
| 28 int compareInternals(Renamable other); | 27 int compareInternals(Renamable other); |
| 29 int getTypeId(); | 28 int get kind; |
| 30 | 29 } |
| 31 String rename() => renamer(this); | 30 |
| 32 } | 31 class GlobalRenamable extends Renamable { |
| 33 | 32 final Entity entity; |
| 34 class ElementRenamable extends Renamable { | 33 |
| 35 final Element element; | 34 GlobalRenamable(this.entity, Set<Node> nodes) |
| 36 | 35 : super(nodes); |
| 37 ElementRenamable(this.element, Set<Node> nodes, _Renamer renamer) | 36 |
| 38 : super(nodes, renamer); | 37 int compareInternals(GlobalRenamable other) => |
| 39 | 38 compareElements(this.entity, other.entity); |
| 40 int compareInternals(ElementRenamable other) => | 39 int get kind => RENAMABLE_TYPE_ELEMENT; |
| 41 compareElements(this.element, other.element); | |
| 42 int getTypeId() => RENAMABLE_TYPE_ELEMENT; | |
| 43 } | 40 } |
| 44 | 41 |
| 45 class MemberRenamable extends Renamable { | 42 class MemberRenamable extends Renamable { |
| 46 final String identifier; | 43 final String identifier; |
| 47 MemberRenamable(this.identifier, Set<Node> nodes, _Renamer renamer) | 44 MemberRenamable(this.identifier, Set<Node> nodes) |
| 48 : super(nodes, renamer); | 45 : super(nodes); |
| 49 int compareInternals(MemberRenamable other) => | 46 int compareInternals(MemberRenamable other) => |
| 50 this.identifier.compareTo(other.identifier); | 47 this.identifier.compareTo(other.identifier); |
| 51 int getTypeId() => RENAMABLE_TYPE_MEMBER; | 48 int get kind => RENAMABLE_TYPE_MEMBER; |
| 52 } | 49 } |
| 53 | 50 |
| 54 class LocalRenamable extends Renamable { | 51 class LocalRenamable extends Renamable { |
| 55 LocalRenamable(Set<Node> nodes, _Renamer renamer) : super(nodes, renamer); | 52 LocalRenamable(Set<Node> nodes) |
| 53 : super(nodes); | |
| 56 int compareInternals(LocalRenamable other) => | 54 int compareInternals(LocalRenamable other) => |
| 57 _compareNodes(sorted(this.nodes, _compareNodes)[0], | 55 _compareNodes(sorted(this.nodes, _compareNodes)[0], |
| 58 sorted(other.nodes, _compareNodes)[0]); | 56 sorted(other.nodes, _compareNodes)[0]); |
| 59 int getTypeId() => RENAMABLE_TYPE_LOCAL; | 57 int get kind => RENAMABLE_TYPE_LOCAL; |
| 60 } | 58 } |
| 61 | 59 |
| 62 /** | 60 /** |
| 63 * Renames only top-level elements that would let to ambiguity if not renamed. | 61 * Renames only top-level elements that would lead to ambiguity if not renamed. |
| 64 */ | 62 */ |
| 65 void renamePlaceholders( | 63 class PlaceholderRenamer { |
| 66 Compiler compiler, | 64 /// After running [computeRenames] this will contain the computed renames. |
| 67 PlaceholderCollector placeholderCollector, | 65 final Map<Node, String> renames = new Map<Node, String>(); |
| 68 Map<Node, String> renames, | 66 /// After running [computeRenames] this will contain the used platform |
| 69 Map<LibraryElement, String> imports, | 67 /// libraries. |
| 70 Set<String> fixedMemberNames, | 68 final Set<LibraryElement> platformImports = new Set<LibraryElement>(); |
| 71 Map<Element, LibraryElement> reexportingLibraries, | 69 |
| 72 bool cutDeclarationTypes, | 70 final Compiler _compiler; |
| 73 {bool uniqueGlobalNaming: false}) { | 71 final Set<String> fixedMemberNames; |
| 74 final Map<LibraryElement, Map<String, String>> renamed | 72 final Map<Element, LibraryElement> reexportingLibraries; |
| 75 = new Map<LibraryElement, Map<String, String>>(); | 73 final bool cutDeclarationTypes; |
| 76 | 74 |
| 77 renameNodes(Iterable<Node> nodes, renamer) { | 75 final Map<Entity, String> _renamedCache = new Map<Entity, String>(); |
| 76 final Map<Entity, Map<String, String>> _privateCache = | |
| 77 new Map<Entity, Map<String, String>>(); | |
| 78 | |
| 79 final MinifyingGenerator _minifyingGenerator = new MinifyingGenerator(); | |
| 80 _NameGenerator _generateUniqueName; | |
| 81 | |
| 82 PlaceholderRenamer(this._compiler, this.fixedMemberNames, | |
| 83 this.reexportingLibraries, {this.cutDeclarationTypes}) { | |
| 84 | |
|
Johnni Winther
2014/08/15 07:49:19
Replace body by ;
sigurdm
2014/08/15 13:06:27
Done.
| |
| 85 } | |
| 86 | |
| 87 void _renameNodes(Iterable<Node> nodes, String renamer(Node node)) { | |
| 78 for (Node node in sorted(nodes, _compareNodes)) { | 88 for (Node node in sorted(nodes, _compareNodes)) { |
| 79 renames[node] = renamer(node); | 89 renames[node] = renamer(node); |
| 80 } | 90 } |
| 81 } | 91 } |
| 82 | 92 |
| 83 sortedForEach(Map<Element, dynamic> map, f) { | 93 |
| 84 for (Element element in sortElements(map.keys)) { | 94 /// Looks up [originalName] in the [_privateCache] cache of [library]. |
| 85 f(element, map[element]); | 95 /// If [originalName] was not renamed before, generate a new name. |
| 86 } | 96 String _getPrivateName(LibraryElement library, String originalName) { |
| 87 } | 97 return _privateCache.putIfAbsent(library, () => new Map<String, String>()) |
| 88 | 98 .putIfAbsent(originalName, () => _generateUniqueName(originalName)); |
| 89 String renameType(DartType type, Function renameElement) { | 99 } |
| 90 if (type.isDynamic) return 'dynamic'; | 100 |
| 91 // TODO(smok): Do not rename type if it is in platform library or | 101 String _renameConstructor(ConstructorPlaceholder placeholder) { |
| 92 // js-helpers. | 102 String name = placeholder.element.name; |
| 93 StringBuffer result = new StringBuffer(renameElement(type.element)); | 103 if (name == '') return ""; |
| 94 if (type is GenericType && !type.treatAsRaw) { | 104 String result = _renameGlobal(placeholder.element); |
| 95 result.write('<'); | 105 return result; |
| 96 List<DartType> arguments = type.typeArguments; | 106 } |
| 97 result.write(renameType(arguments.first, renameElement)); | 107 |
| 98 for (int index = 1; index < arguments.length; index++) { | 108 String _renameGlobal(Entity entity) { |
| 99 result.write(','); | 109 assert(entity is! Element || |
| 100 result.write(renameType(arguments[index], renameElement)); | 110 Elements.isErroneousElement(entity) || |
| 101 } | 111 Elements.isStaticOrTopLevel(entity) || |
| 102 result.write('>'); | 112 entity is TypeVariableElement); |
| 103 } | |
| 104 return result.toString(); | |
| 105 } | |
| 106 | |
| 107 String renameConstructor(Element element, ConstructorPlaceholder placeholder, | |
| 108 Function renameString, Function renameElement) { | |
| 109 assert(element.isConstructor); | |
| 110 StringBuffer result = new StringBuffer(); | |
| 111 String name = element.name; | |
| 112 if (element.name != '') { | |
| 113 // Named constructor or factory. Is there a more reliable way to check | |
| 114 // this case? | |
| 115 if (!placeholder.isRedirectingCall) { | |
| 116 result.write(renameType(placeholder.type, renameElement)); | |
| 117 result.write('.'); | |
| 118 } | |
| 119 if (!element.library.isPlatformLibrary) { | |
| 120 name = renameString(element.library, name); | |
| 121 } | |
| 122 result.write(name); | |
| 123 } else { | |
| 124 assert(!placeholder.isRedirectingCall); | |
| 125 result.write(renameType(placeholder.type, renameElement)); | |
| 126 } | |
| 127 return result.toString(); | |
| 128 } | |
| 129 | |
| 130 Function makeElementRenamer(rename, generateUniqueName) => (element) { | |
| 131 assert(Elements.isErroneousElement(element) || | |
| 132 Elements.isStaticOrTopLevel(element) || | |
| 133 element is TypeVariableElement); | |
| 134 // TODO(smok): We may want to reuse class static field and method names. | 113 // TODO(smok): We may want to reuse class static field and method names. |
| 135 String originalName = element.name; | 114 if (entity is Element) { |
| 136 LibraryElement library = element.library; | 115 LibraryElement library = entity.library; |
| 137 if (identical(element.library, compiler.coreLibrary)) { | 116 if (reexportingLibraries.containsKey(entity)) { |
| 138 return originalName; | 117 library = reexportingLibraries[entity]; |
| 139 } | 118 } |
| 140 if (library.isPlatformLibrary) { | 119 if (library.isPlatformLibrary) { |
| 141 assert(element.isTopLevel); | 120 if (library != _compiler.coreLibrary) { |
| 142 if (reexportingLibraries.containsKey(element)) { | 121 platformImports.add(library); |
| 143 library = reexportingLibraries[element]; | 122 } |
| 144 } | 123 if (library.isInternalLibrary) { |
| 145 if (!library.isInternalLibrary) { | 124 throw new SpannableAssertionFailure(entity, |
| 146 final prefix = | 125 "Internal library $library should never have been imported from " |
| 147 imports.putIfAbsent(library, () => generateUniqueName('p')); | 126 "the code compiled by dart2dart."); |
| 148 return '$prefix.$originalName'; | 127 } |
| 149 } | 128 return entity.name; |
| 150 } | 129 } |
| 151 | 130 } |
| 152 return rename(library, originalName); | 131 |
| 153 }; | 132 // Look up in [_renamedCache] for a name for [entity] . |
| 154 | 133 // If it was not renamed before, generate a new name. |
| 155 Function makeRenamer(generateUniqueName) => | 134 return _renamedCache.putIfAbsent(entity, |
| 156 (library, originalName) => | 135 () => _generateUniqueName(entity.name)); |
| 157 renamed.putIfAbsent(library, () => {}) | 136 } |
| 158 .putIfAbsent(originalName, | 137 |
| 159 () => generateUniqueName(originalName)); | 138 void _computeMinifiedRenames(PlaceholderCollector placeholderCollector, |
| 160 | 139 Set<String> allNamedParameterIdentifiers, |
| 161 // Renamer function that takes library and original name and returns a new | 140 Set<String> forbiddenIdentifiers) { |
| 162 // name for given identifier. | 141 String generateUniqueMinifiedName() { |
| 163 Function rename; | 142 return _minifyingGenerator.generate((name) => |
| 164 Function renameElement; | 143 forbiddenIdentifiers.contains(name) |
| 165 // A function that takes original identifier name and generates a new unique | 144 || allNamedParameterIdentifiers.contains(name)); |
| 166 // identifier. | 145 } |
| 167 Function generateUniqueName; | 146 _generateUniqueName = (_) => generateUniqueMinifiedName(); |
| 168 | |
| 169 Set<String> allNamedParameterIdentifiers = new Set<String>(); | |
| 170 for (var functionScope in placeholderCollector.functionScopes.values) { | |
| 171 allNamedParameterIdentifiers.addAll(functionScope.parameterIdentifiers); | |
| 172 } | |
| 173 | |
| 174 if (compiler.enableMinification) { | |
| 175 MinifyingGenerator generator = new MinifyingGenerator(); | |
| 176 Set<String> forbiddenIdentifiers = new Set<String>.from(['main']); | |
| 177 forbiddenIdentifiers.addAll(Keyword.keywords.keys); | |
| 178 forbiddenIdentifiers.addAll(fixedMemberNames); | |
| 179 generateUniqueName = (_) => | |
| 180 generator.generate((name) => | |
| 181 forbiddenIdentifiers.contains(name) | |
| 182 || allNamedParameterIdentifiers.contains(name)); | |
| 183 rename = makeRenamer(generateUniqueName); | |
| 184 renameElement = makeElementRenamer(rename, generateUniqueName); | |
| 185 | |
| 186 List<Set<Node>> allLocals = new List<Set<Node>>(); | |
| 187 | |
| 188 // Build a list sorted by usage of local nodes that will be renamed to | 147 // Build a list sorted by usage of local nodes that will be renamed to |
| 189 // the same identifier. So the top-used local variables in all functions | 148 // the same identifier. So the top-used local variables in all functions |
| 190 // will be renamed first and will all share the same new identifier. | 149 // will be renamed first and will all share the same new identifier. |
| 191 for (var functionScope in placeholderCollector.functionScopes.values) { | 150 int maxLength = placeholderCollector.functionScopes.values.fold(0, |
| 151 (a, b) => max(a, b.localPlaceholders.length)); | |
| 152 | |
| 153 List<Set<Node>> allLocals = new List<Set<Node>> | |
| 154 .generate(maxLength, (_) => new Set<Node>()); | |
| 155 | |
| 156 for (FunctionScope functionScope | |
| 157 in placeholderCollector.functionScopes.values) { | |
| 192 // Add current sorted local identifiers to the whole sorted list | 158 // Add current sorted local identifiers to the whole sorted list |
| 193 // of all local identifiers for all functions. | 159 // of all local identifiers for all functions. |
| 194 List<LocalPlaceholder> currentSortedPlaceholders = | 160 List<LocalPlaceholder> currentSortedPlaceholders = |
| 195 sorted(functionScope.localPlaceholders, | 161 sorted(functionScope.localPlaceholders, |
| 196 compareBy((LocalPlaceholder ph) => -ph.nodes.length)); | 162 compareBy((LocalPlaceholder ph) => -ph.nodes.length)); |
| 197 List<Set<Node>> currentSortedNodes = | 163 |
| 198 currentSortedPlaceholders.map((ph) => ph.nodes).toList(); | 164 List<Set<Node>> currentSortedNodes = currentSortedPlaceholders |
| 199 // Make room in all sorted locals list for new stuff. | 165 .map((LocalPlaceholder ph) => ph.nodes).toList(); |
| 200 while (currentSortedNodes.length > allLocals.length) { | 166 |
| 201 allLocals.add(new Set<Node>()); | |
| 202 } | |
| 203 for (int i = 0; i < currentSortedNodes.length; i++) { | 167 for (int i = 0; i < currentSortedNodes.length; i++) { |
| 204 allLocals[i].addAll(currentSortedNodes[i]); | 168 allLocals[i].addAll(currentSortedNodes[i]); |
| 205 } | 169 } |
| 206 } | 170 } |
| 207 | 171 |
| 208 // Rename elements, members and locals together based on their usage count, | 172 // Rename elements, members and locals together based on their usage |
| 209 // otherwise when we rename elements first there will be no good identifiers | 173 // count, otherwise when we rename elements first there will be no good |
| 210 // left for members even if they are used often. | 174 // identifiers left for members even if they are used often. |
| 211 String elementRenamer(ElementRenamable elementRenamable) => | 175 List<Renamable> renamables = new List<Renamable>(); |
| 212 renameElement(elementRenamable.element); | |
| 213 String memberRenamer(MemberRenamable memberRenamable) => | |
| 214 generator.generate(forbiddenIdentifiers.contains); | |
| 215 Function localRenamer = generateUniqueName; | |
| 216 List<Renamable> renamables = []; | |
| 217 placeholderCollector.elementNodes.forEach( | 176 placeholderCollector.elementNodes.forEach( |
| 218 (Element element, Set<Node> nodes) { | 177 (Element element, Set<Node> nodes) { |
| 219 renamables.add(new ElementRenamable(element, nodes, elementRenamer)); | 178 renamables.add(new GlobalRenamable(element, nodes)); |
| 220 }); | 179 }); |
| 221 placeholderCollector.memberPlaceholders.forEach( | 180 placeholderCollector.memberPlaceholders.forEach( |
| 222 (String memberName, Set<Identifier> identifiers) { | 181 (String memberName, Set<Identifier> identifiers) { |
| 223 renamables.add( | 182 renamables.add( |
| 224 new MemberRenamable(memberName, identifiers, memberRenamer)); | 183 new MemberRenamable(memberName, identifiers)); |
| 225 }); | 184 }); |
| 226 for (Set<Node> localIdentifiers in allLocals) { | 185 for (Set<Node> localIdentifiers in allLocals) { |
| 227 renamables.add(new LocalRenamable(localIdentifiers, localRenamer)); | 186 renamables.add(new LocalRenamable(localIdentifiers)); |
| 228 } | 187 } |
| 229 renamables.sort((Renamable renamable1, Renamable renamable2) => | 188 renamables.sort(); |
| 230 renamable1.compareTo(renamable2)); | |
| 231 for (Renamable renamable in renamables) { | 189 for (Renamable renamable in renamables) { |
| 232 String newName = renamable.rename(); | 190 String newName; |
| 233 renameNodes(renamable.nodes, (_) => newName); | 191 if (renamable is GlobalRenamable) { |
|
Johnni Winther
2014/08/15 07:49:19
These could be different implementations of a [cre
sigurdm
2014/08/15 13:06:27
Done.
| |
| 234 } | 192 newName = _renameGlobal(renamable.entity); |
| 235 } else { | 193 } else if (renamable is MemberRenamable) { |
| 236 // Never rename anything to 'main'. | 194 newName = _minifyingGenerator.generate(forbiddenIdentifiers.contains); |
| 237 final usedTopLevelOrMemberIdentifiers = new Set<String>(); | 195 } else if (renamable is LocalRenamable) { |
| 238 usedTopLevelOrMemberIdentifiers.add('main'); | 196 newName = generateUniqueMinifiedName(); |
| 239 usedTopLevelOrMemberIdentifiers.addAll(fixedMemberNames); | 197 } else { |
| 240 generateUniqueName = (originalName) { | 198 throw "Unknown type of renamable"; |
| 241 String newName = conservativeGenerator( | 199 } |
| 242 originalName, (name) => | 200 _renameNodes(renamable.nodes, (_) => newName); |
| 243 usedTopLevelOrMemberIdentifiers.contains(name) | 201 } |
| 244 || allNamedParameterIdentifiers.contains(name)); | 202 } |
| 245 usedTopLevelOrMemberIdentifiers.add(newName); | 203 |
| 204 void _computeNonMinifiedRenames(PlaceholderCollector placeholderCollector, | |
| 205 Set<String> allNamedParameterIdentifiers, | |
| 206 Set<String> forbiddenIdentifiers) { | |
| 207 String generateUniqueNonminifiedName(originalName) { | |
| 208 String newName = conservativeGenerator(originalName, (name) { | |
| 209 return forbiddenIdentifiers.contains(name) || | |
| 210 allNamedParameterIdentifiers.contains(name); | |
| 211 }); | |
| 212 forbiddenIdentifiers.add(newName); | |
| 246 return newName; | 213 return newName; |
| 247 }; | 214 } |
| 248 rename = makeRenamer(generateUniqueName); | 215 _generateUniqueName = generateUniqueNonminifiedName; |
| 249 renameElement = makeElementRenamer(rename, generateUniqueName); | |
| 250 // Rename elements. | 216 // Rename elements. |
| 251 sortedForEach(placeholderCollector.elementNodes, | 217 placeholderCollector.elementNodes.forEach( |
| 252 (Element element, Set<Node> nodes) { | 218 (Element element, Set<Node> nodes) { |
| 253 renameNodes(nodes, (_) => renameElement(element)); | 219 _renameNodes(nodes, (_) => _renameGlobal(element)); |
| 254 }); | 220 }); |
| 255 | 221 |
| 256 // Rename locals. | 222 // Rename locals. |
| 257 sortedForEach(placeholderCollector.functionScopes, | 223 placeholderCollector.functionScopes.forEach( |
| 258 (functionElement, functionScope) { | 224 (functionElement, functionScope) { |
| 259 Set<LocalPlaceholder> placeholders = functionScope.localPlaceholders; | 225 Set<LocalPlaceholder> placeholders = functionScope.localPlaceholders; |
| 260 Set<String> memberIdentifiers = new Set<String>(); | 226 Set<String> memberIdentifiers = new Set<String>(); |
| 261 if (functionElement.enclosingClass != null) { | 227 if (functionElement.enclosingClass != null) { |
| 262 functionElement.enclosingClass.forEachMember( | 228 functionElement.enclosingClass.forEachMember( |
| 263 (enclosingClass, member) { | 229 (enclosingClass, member) { |
| 264 memberIdentifiers.add(member.name); | 230 memberIdentifiers.add(member.name); |
| 265 }); | 231 }); |
| 266 } | 232 } |
| 267 Set<String> usedLocalIdentifiers = new Set<String>(); | 233 Set<String> usedLocalIdentifiers = new Set<String>(); |
| 268 for (LocalPlaceholder placeholder in placeholders) { | 234 for (LocalPlaceholder placeholder in placeholders) { |
| 269 String nextId = | 235 String nextId = |
| 270 conservativeGenerator(placeholder.identifier, (name) => | 236 conservativeGenerator(placeholder.identifier, (name) => |
| 271 functionScope.parameterIdentifiers.contains(name) | 237 functionScope.parameterIdentifiers.contains(name) |
| 272 || usedTopLevelOrMemberIdentifiers.contains(name) | 238 || forbiddenIdentifiers.contains(name) |
| 273 || usedLocalIdentifiers.contains(name) | 239 || usedLocalIdentifiers.contains(name) |
| 274 || memberIdentifiers.contains(name)); | 240 || memberIdentifiers.contains(name)); |
| 275 usedLocalIdentifiers.add(nextId); | 241 usedLocalIdentifiers.add(nextId); |
| 276 renameNodes(placeholder.nodes, (_) => nextId); | 242 _renameNodes(placeholder.nodes, (_) => nextId); |
| 277 } | 243 } |
| 278 }); | 244 }); |
| 279 | 245 |
| 280 final usedMemberIdentifiers = new Set<String>.from(fixedMemberNames); | |
| 281 // Do not rename members to top-levels, that allows to avoid renaming | 246 // Do not rename members to top-levels, that allows to avoid renaming |
| 282 // members to constructors. | 247 // members to constructors. |
| 283 usedMemberIdentifiers.addAll(usedTopLevelOrMemberIdentifiers); | |
| 284 placeholderCollector.memberPlaceholders.forEach((identifier, nodes) { | 248 placeholderCollector.memberPlaceholders.forEach((identifier, nodes) { |
| 285 String newIdentifier = conservativeGenerator( | 249 String newIdentifier = conservativeGenerator( |
| 286 identifier, usedMemberIdentifiers.contains); | 250 identifier, forbiddenIdentifiers.contains); |
| 287 renameNodes(nodes, (_) => newIdentifier); | 251 _renameNodes(nodes, (_) => newIdentifier); |
| 288 }); | 252 }); |
| 289 } | 253 } |
| 290 | 254 |
| 291 // Rename constructors. | 255 /// Finds renamings for all the placeholders in [placeholderCollector] and |
| 292 sortedForEach(placeholderCollector.constructorPlaceholders, | 256 /// stores them in [renames]. |
| 293 (Element constructor, List<ConstructorPlaceholder> placeholders) { | 257 /// Also adds to [platformImports] all the platform-libraries that are used. |
| 294 for (ConstructorPlaceholder ph in placeholders) { | 258 void computeRenames(PlaceholderCollector placeholderCollector) { |
| 295 renames[ph.node] = | 259 Set<String> allNamedParameterIdentifiers = new Set<String>(); |
| 296 renameConstructor(constructor, ph, rename, renameElement); | 260 for (FunctionScope functionScope in |
| 297 } | 261 placeholderCollector.functionScopes.values) { |
| 298 }); | 262 allNamedParameterIdentifiers.addAll(functionScope.parameterIdentifiers); |
| 299 sortedForEach(placeholderCollector.privateNodes, (library, nodes) { | 263 } |
| 300 renameNodes(nodes, (node) => rename(library, node.source)); | 264 |
| 301 }); | 265 Set<String> forbiddenIdentifiers = new Set<String>.from(fixedMemberNames); |
| 302 renameNodes(placeholderCollector.unresolvedNodes, | 266 forbiddenIdentifiers.addAll(Keyword.keywords.keys); |
| 303 (_) => generateUniqueName('Unresolved')); | 267 forbiddenIdentifiers.add('main'); |
| 304 renameNodes(placeholderCollector.nullNodes, (_) => ''); | 268 |
| 305 if (cutDeclarationTypes) { | 269 if (_compiler.enableMinification) { |
| 306 for (DeclarationTypePlaceholder placeholder in | 270 _computeMinifiedRenames(placeholderCollector, |
| 307 placeholderCollector.declarationTypePlaceholders) { | 271 allNamedParameterIdentifiers, |
| 308 renames[placeholder.typeNode] = placeholder.requiresVar ? 'var' : ''; | 272 forbiddenIdentifiers); |
| 273 | |
| 274 } else { | |
| 275 _computeNonMinifiedRenames(placeholderCollector, | |
| 276 allNamedParameterIdentifiers, | |
| 277 forbiddenIdentifiers); | |
| 278 } | |
| 279 | |
| 280 // Rename constructors. | |
| 281 for (ConstructorPlaceholder placeholder in | |
| 282 placeholderCollector.constructorPlaceholders) { | |
| 283 renames[placeholder.node] = | |
| 284 _renameConstructor(placeholder); | |
| 285 }; | |
| 286 | |
| 287 // Rename private identifiers uniquely for each library. | |
| 288 placeholderCollector.privateNodes.forEach( | |
| 289 (Element library, Set<Identifier> identifiers) { | |
|
Johnni Winther
2014/08/15 07:49:19
Element library -> LibraryElement library
sigurdm
2014/08/15 13:06:27
Done.
| |
| 290 for (Identifier identifier in identifiers) { | |
| 291 renames[identifier] = _getPrivateName(library, identifier.source); | |
| 292 } | |
| 293 }); | |
| 294 | |
| 295 // Rename unresolved nodes, to make sure they still do not resolve. | |
| 296 for (Node node in placeholderCollector.unresolvedNodes) { | |
| 297 renames[node] = _generateUniqueName('Unresolved'); | |
| 298 } | |
| 299 | |
| 300 // Erase prefixes that are now not needed. | |
| 301 for (Node node in placeholderCollector.prefixNodesToErase) { | |
| 302 renames[node] = ''; | |
| 303 } | |
| 304 | |
| 305 if (cutDeclarationTypes) { | |
| 306 for (DeclarationTypePlaceholder placeholder in | |
| 307 placeholderCollector.declarationTypePlaceholders) { | |
| 308 renames[placeholder.typeNode] = placeholder.requiresVar ? 'var' : ''; | |
| 309 } | |
| 309 } | 310 } |
| 310 } | 311 } |
| 311 } | 312 } |
| 312 | 313 |
| 313 /** | 314 /** |
| 314 * Generates mini ID based on index. | 315 * Generates mini ID based on index. |
| 315 * In other words, it converts index to visual representation | 316 * In other words, it converts index to visual representation |
| 316 * as if digits are given characters. | 317 * as if digits are given characters. |
| 317 */ | 318 */ |
| 318 String generateMiniId(int index) { | 319 String generateMiniId(int index) { |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 334 resultBuilder.write(otherCharsAlphabet[index]); | 335 resultBuilder.write(otherCharsAlphabet[index]); |
| 335 return resultBuilder.toString(); | 336 return resultBuilder.toString(); |
| 336 } | 337 } |
| 337 | 338 |
| 338 | 339 |
| 339 /** Always tries to return original identifier name unless it is forbidden. */ | 340 /** Always tries to return original identifier name unless it is forbidden. */ |
| 340 String conservativeGenerator(String name, bool isForbidden(String name)) { | 341 String conservativeGenerator(String name, bool isForbidden(String name)) { |
| 341 String result = name; | 342 String result = name; |
| 342 int index = 0; | 343 int index = 0; |
| 343 while (isForbidden(result)) { | 344 while (isForbidden(result)) { |
| 344 result = '${generateMiniId(index++)}_$name'; | 345 result = '${name}_${generateMiniId(index++)}'; |
| 345 } | 346 } |
| 346 return result; | 347 return result; |
| 347 } | 348 } |
| 348 | 349 |
| 349 | 350 |
| 350 /** Always tries to generate the most compact identifier. */ | 351 /** Always tries to generate the most compact identifier. */ |
| 351 class MinifyingGenerator { | 352 class MinifyingGenerator { |
| 352 int index = 0; | 353 int index = 0; |
| 353 | 354 |
| 354 MinifyingGenerator(); | 355 MinifyingGenerator(); |
| 355 | 356 |
| 356 String generate(bool isForbidden(String name)) { | 357 String generate(bool isForbidden(String name)) { |
| 357 String result; | 358 String result; |
| 358 do { | 359 do { |
| 359 result = generateMiniId(index++); | 360 result = generateMiniId(index++); |
| 360 } while (isForbidden(result)); | 361 } while (isForbidden(result)); |
| 361 return result; | 362 return result; |
| 362 } | 363 } |
| 363 } | 364 } |
| OLD | NEW |