1 /* 2 * Copyright (c) 2018, Google LLC. All rights reserved. 3 * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. Oracle designates this 9 * particular file as subject to the "Classpath" exception as provided 10 * by Oracle in the LICENSE file that accompanied this code. 11 * 12 * This code is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 * version 2 for more details (a copy is included in the LICENSE file that 16 * accompanied this code). 17 * 18 * You should have received a copy of the GNU General Public License version 19 * 2 along with this work; if not, write to the Free Software Foundation, 20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 21 * 22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 23 * or visit www.oracle.com if you need additional information or have any 24 * questions. 25 */ 26 27 package com.sun.tools.javac.comp; 28 29 import com.sun.tools.javac.code.Symbol; 30 import com.sun.tools.javac.tree.JCTree; 31 import com.sun.tools.javac.tree.JCTree.JCAnnotatedType; 32 import com.sun.tools.javac.tree.JCTree.JCAnnotation; 33 import com.sun.tools.javac.tree.JCTree.JCArrayAccess; 34 import com.sun.tools.javac.tree.JCTree.JCArrayTypeTree; 35 import com.sun.tools.javac.tree.JCTree.JCAssert; 36 import com.sun.tools.javac.tree.JCTree.JCAssign; 37 import com.sun.tools.javac.tree.JCTree.JCAssignOp; 38 import com.sun.tools.javac.tree.JCTree.JCBinary; 39 import com.sun.tools.javac.tree.JCTree.JCBindingPattern; 40 import com.sun.tools.javac.tree.JCTree.JCBlock; 41 import com.sun.tools.javac.tree.JCTree.JCBreak; 42 import com.sun.tools.javac.tree.JCTree.JCCase; 43 import com.sun.tools.javac.tree.JCTree.JCCatch; 44 import com.sun.tools.javac.tree.JCTree.JCClassDecl; 45 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; 46 import com.sun.tools.javac.tree.JCTree.JCConditional; 47 import com.sun.tools.javac.tree.JCTree.JCContinue; 48 import com.sun.tools.javac.tree.JCTree.JCDoWhileLoop; 49 import com.sun.tools.javac.tree.JCTree.JCEnhancedForLoop; 50 import com.sun.tools.javac.tree.JCTree.JCErroneous; 51 import com.sun.tools.javac.tree.JCTree.JCExports; 52 import com.sun.tools.javac.tree.JCTree.JCExpressionStatement; 53 import com.sun.tools.javac.tree.JCTree.JCFieldAccess; 54 import com.sun.tools.javac.tree.JCTree.JCForLoop; 55 import com.sun.tools.javac.tree.JCTree.JCIdent; 56 import com.sun.tools.javac.tree.JCTree.JCIf; 57 import com.sun.tools.javac.tree.JCTree.JCImport; 58 import com.sun.tools.javac.tree.JCTree.JCInstanceOf; 59 import com.sun.tools.javac.tree.JCTree.JCLabeledStatement; 60 import com.sun.tools.javac.tree.JCTree.JCLambda; 61 import com.sun.tools.javac.tree.JCTree.JCLiteral; 62 import com.sun.tools.javac.tree.JCTree.JCMemberReference; 63 import com.sun.tools.javac.tree.JCTree.JCMethodDecl; 64 import com.sun.tools.javac.tree.JCTree.JCMethodInvocation; 65 import com.sun.tools.javac.tree.JCTree.JCModifiers; 66 import com.sun.tools.javac.tree.JCTree.JCModuleDecl; 67 import com.sun.tools.javac.tree.JCTree.JCNewArray; 68 import com.sun.tools.javac.tree.JCTree.JCNewClass; 69 import com.sun.tools.javac.tree.JCTree.JCOpens; 70 import com.sun.tools.javac.tree.JCTree.JCPackageDecl; 71 import com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree; 72 import com.sun.tools.javac.tree.JCTree.JCProvides; 73 import com.sun.tools.javac.tree.JCTree.JCRequires; 74 import com.sun.tools.javac.tree.JCTree.JCReturn; 75 import com.sun.tools.javac.tree.JCTree.JCSwitch; 76 import com.sun.tools.javac.tree.JCTree.JCSwitchExpression; 77 import com.sun.tools.javac.tree.JCTree.JCSynchronized; 78 import com.sun.tools.javac.tree.JCTree.JCThrow; 79 import com.sun.tools.javac.tree.JCTree.JCTry; 80 import com.sun.tools.javac.tree.JCTree.JCTypeApply; 81 import com.sun.tools.javac.tree.JCTree.JCTypeCast; 82 import com.sun.tools.javac.tree.JCTree.JCTypeIntersection; 83 import com.sun.tools.javac.tree.JCTree.JCTypeParameter; 84 import com.sun.tools.javac.tree.JCTree.JCTypeUnion; 85 import com.sun.tools.javac.tree.JCTree.JCUnary; 86 import com.sun.tools.javac.tree.JCTree.JCUses; 87 import com.sun.tools.javac.tree.JCTree.JCVariableDecl; 88 import com.sun.tools.javac.tree.JCTree.JCWhileLoop; 89 import com.sun.tools.javac.tree.JCTree.JCWildcard; 90 import com.sun.tools.javac.tree.JCTree.JCYield; 91 import com.sun.tools.javac.tree.JCTree.LetExpr; 92 import com.sun.tools.javac.tree.JCTree.TypeBoundKind; 93 import com.sun.tools.javac.tree.TreeInfo; 94 import com.sun.tools.javac.tree.TreeScanner; 95 import com.sun.tools.javac.util.List; 96 import java.util.Collection; 97 import java.util.HashMap; 98 import java.util.Iterator; 99 import java.util.Map; 100 import java.util.Objects; 101 102 /** A visitor that compares two lambda bodies for structural equality. */ 103 public class TreeDiffer extends TreeScanner { 104 TreeDiffer( Collection<? extends Symbol> symbols, Collection<? extends Symbol> otherSymbols)105 public TreeDiffer( 106 Collection<? extends Symbol> symbols, Collection<? extends Symbol> otherSymbols) { 107 this.equiv = equiv(symbols, otherSymbols); 108 } 109 equiv( Collection<? extends Symbol> symbols, Collection<? extends Symbol> otherSymbols)110 private static Map<Symbol, Symbol> equiv( 111 Collection<? extends Symbol> symbols, Collection<? extends Symbol> otherSymbols) { 112 Map<Symbol, Symbol> result = new HashMap<>(); 113 Iterator<? extends Symbol> it = otherSymbols.iterator(); 114 for (Symbol symbol : symbols) { 115 if (!it.hasNext()) break; 116 result.put(symbol, it.next()); 117 } 118 return result; 119 } 120 121 private JCTree parameter; 122 private boolean result; 123 private Map<Symbol, Symbol> equiv = new HashMap<>(); 124 scan(JCTree tree, JCTree parameter)125 public boolean scan(JCTree tree, JCTree parameter) { 126 if (tree == null || parameter == null) { 127 return tree == null && parameter == null; 128 } 129 tree = TreeInfo.skipParens(tree); 130 parameter = TreeInfo.skipParens(parameter); 131 if (tree.type != null 132 && tree.type.constValue() != null 133 && parameter.type != null 134 && parameter.type.constValue() != null) { 135 return Objects.equals(tree.type.constValue(), parameter.type.constValue()); 136 } 137 if (tree.getTag() != parameter.getTag()) { 138 return false; 139 } 140 JCTree prevParameter = this.parameter; 141 boolean prevResult = this.result; 142 try { 143 this.parameter = parameter; 144 tree.accept(this); 145 return result; 146 } finally { 147 this.parameter = prevParameter; 148 this.result = prevResult; 149 } 150 } 151 scan(Iterable<? extends JCTree> xs, Iterable<? extends JCTree> ys)152 private boolean scan(Iterable<? extends JCTree> xs, Iterable<? extends JCTree> ys) { 153 if (xs == null || ys == null) { 154 return xs == null && ys == null; 155 } 156 Iterator<? extends JCTree> x = xs.iterator(); 157 Iterator<? extends JCTree> y = ys.iterator(); 158 while (x.hasNext() && y.hasNext()) { 159 if (!scan(x.next(), y.next())) { 160 return false; 161 } 162 } 163 return !x.hasNext() && !y.hasNext(); 164 } 165 scanDimAnnotations(List<List<JCAnnotation>> xs, List<List<JCAnnotation>> ys)166 private boolean scanDimAnnotations(List<List<JCAnnotation>> xs, List<List<JCAnnotation>> ys) { 167 if (xs == null || ys == null) { 168 return xs == null && ys == null; 169 } 170 Iterator<List<JCAnnotation>> x = xs.iterator(); 171 Iterator<List<JCAnnotation>> y = ys.iterator(); 172 while (x.hasNext() && y.hasNext()) { 173 if (!scan(x.next(), y.next())) { 174 return false; 175 } 176 } 177 return !x.hasNext() && !y.hasNext(); 178 } 179 180 @Override visitIdent(JCIdent tree)181 public void visitIdent(JCIdent tree) { 182 JCIdent that = (JCIdent) parameter; 183 // Identifiers are a special case: we want to ensure the identifiers correspond to the 184 // same symbols (rather than just having the same name), but also consider lambdas 185 // equal if they differ only in the names of the parameters. 186 Symbol symbol = tree.sym; 187 Symbol otherSymbol = that.sym; 188 if (symbol != null && otherSymbol != null) { 189 if (Objects.equals(equiv.get(symbol), otherSymbol)) { 190 result = true; 191 return; 192 } 193 } 194 result = tree.sym == that.sym; 195 } 196 197 @Override visitSelect(JCFieldAccess tree)198 public void visitSelect(JCFieldAccess tree) { 199 JCFieldAccess that = (JCFieldAccess) parameter; 200 result = scan(tree.selected, that.selected) && tree.sym == that.sym; 201 } 202 203 @Override visitAnnotatedType(JCAnnotatedType tree)204 public void visitAnnotatedType(JCAnnotatedType tree) { 205 JCAnnotatedType that = (JCAnnotatedType) parameter; 206 result = 207 scan(tree.annotations, that.annotations) 208 && scan(tree.underlyingType, that.underlyingType); 209 } 210 211 @Override visitAnnotation(JCAnnotation tree)212 public void visitAnnotation(JCAnnotation tree) { 213 JCAnnotation that = (JCAnnotation) parameter; 214 result = scan(tree.annotationType, that.annotationType) && scan(tree.args, that.args); 215 } 216 217 @Override visitApply(JCMethodInvocation tree)218 public void visitApply(JCMethodInvocation tree) { 219 JCMethodInvocation that = (JCMethodInvocation) parameter; 220 result = 221 scan(tree.typeargs, that.typeargs) 222 && scan(tree.meth, that.meth) 223 && scan(tree.args, that.args) 224 && tree.polyKind == that.polyKind; 225 } 226 227 @Override visitAssert(JCAssert tree)228 public void visitAssert(JCAssert tree) { 229 JCAssert that = (JCAssert) parameter; 230 result = scan(tree.cond, that.cond) && scan(tree.detail, that.detail); 231 } 232 233 @Override visitAssign(JCAssign tree)234 public void visitAssign(JCAssign tree) { 235 JCAssign that = (JCAssign) parameter; 236 result = scan(tree.lhs, that.lhs) && scan(tree.rhs, that.rhs); 237 } 238 239 @Override visitAssignop(JCAssignOp tree)240 public void visitAssignop(JCAssignOp tree) { 241 JCAssignOp that = (JCAssignOp) parameter; 242 result = 243 scan(tree.lhs, that.lhs) 244 && scan(tree.rhs, that.rhs) 245 && tree.operator == that.operator; 246 } 247 248 @Override visitBinary(JCBinary tree)249 public void visitBinary(JCBinary tree) { 250 JCBinary that = (JCBinary) parameter; 251 result = 252 scan(tree.lhs, that.lhs) 253 && scan(tree.rhs, that.rhs) 254 && tree.operator == that.operator; 255 } 256 257 @Override visitBindingPattern(JCBindingPattern tree)258 public void visitBindingPattern(JCBindingPattern tree) { 259 JCBindingPattern that = (JCBindingPattern) parameter; 260 result = 261 scan(tree.vartype, that.vartype) 262 && tree.name == that.name; 263 if (!result) { 264 return; 265 } 266 equiv.put(tree.symbol, that.symbol); 267 } 268 269 @Override visitBlock(JCBlock tree)270 public void visitBlock(JCBlock tree) { 271 JCBlock that = (JCBlock) parameter; 272 result = tree.flags == that.flags && scan(tree.stats, that.stats); 273 } 274 275 @Override visitBreak(JCBreak tree)276 public void visitBreak(JCBreak tree) { 277 JCBreak that = (JCBreak) parameter; 278 result = tree.label == that.label; 279 } 280 281 @Override visitYield(JCYield tree)282 public void visitYield(JCYield tree) { 283 JCYield that = (JCYield) parameter; 284 result = scan(tree.value, that.value); 285 } 286 287 @Override visitCase(JCCase tree)288 public void visitCase(JCCase tree) { 289 JCCase that = (JCCase) parameter; 290 result = scan(tree.pats, that.pats) && scan(tree.stats, that.stats); 291 } 292 293 @Override visitCatch(JCCatch tree)294 public void visitCatch(JCCatch tree) { 295 JCCatch that = (JCCatch) parameter; 296 result = scan(tree.param, that.param) && scan(tree.body, that.body); 297 } 298 299 @Override visitClassDef(JCClassDecl tree)300 public void visitClassDef(JCClassDecl tree) { 301 JCClassDecl that = (JCClassDecl) parameter; 302 result = 303 scan(tree.mods, that.mods) 304 && tree.name == that.name 305 && scan(tree.typarams, that.typarams) 306 && scan(tree.extending, that.extending) 307 && scan(tree.implementing, that.implementing) 308 && scan(tree.defs, that.defs); 309 } 310 311 @Override visitConditional(JCConditional tree)312 public void visitConditional(JCConditional tree) { 313 JCConditional that = (JCConditional) parameter; 314 result = 315 scan(tree.cond, that.cond) 316 && scan(tree.truepart, that.truepart) 317 && scan(tree.falsepart, that.falsepart); 318 } 319 320 @Override visitContinue(JCContinue tree)321 public void visitContinue(JCContinue tree) { 322 JCContinue that = (JCContinue) parameter; 323 result = tree.label == that.label; 324 } 325 326 @Override visitDoLoop(JCDoWhileLoop tree)327 public void visitDoLoop(JCDoWhileLoop tree) { 328 JCDoWhileLoop that = (JCDoWhileLoop) parameter; 329 result = scan(tree.body, that.body) && scan(tree.cond, that.cond); 330 } 331 332 @Override visitErroneous(JCErroneous tree)333 public void visitErroneous(JCErroneous tree) { 334 JCErroneous that = (JCErroneous) parameter; 335 result = scan(tree.errs, that.errs); 336 } 337 338 @Override visitExec(JCExpressionStatement tree)339 public void visitExec(JCExpressionStatement tree) { 340 JCExpressionStatement that = (JCExpressionStatement) parameter; 341 result = scan(tree.expr, that.expr); 342 } 343 344 @Override visitExports(JCExports tree)345 public void visitExports(JCExports tree) { 346 JCExports that = (JCExports) parameter; 347 result = scan(tree.qualid, that.qualid) && scan(tree.moduleNames, that.moduleNames); 348 } 349 350 @Override visitForLoop(JCForLoop tree)351 public void visitForLoop(JCForLoop tree) { 352 JCForLoop that = (JCForLoop) parameter; 353 result = 354 scan(tree.init, that.init) 355 && scan(tree.cond, that.cond) 356 && scan(tree.step, that.step) 357 && scan(tree.body, that.body); 358 } 359 360 @Override visitForeachLoop(JCEnhancedForLoop tree)361 public void visitForeachLoop(JCEnhancedForLoop tree) { 362 JCEnhancedForLoop that = (JCEnhancedForLoop) parameter; 363 result = 364 scan(tree.var, that.var) 365 && scan(tree.expr, that.expr) 366 && scan(tree.body, that.body); 367 } 368 369 @Override visitIf(JCIf tree)370 public void visitIf(JCIf tree) { 371 JCIf that = (JCIf) parameter; 372 result = 373 scan(tree.cond, that.cond) 374 && scan(tree.thenpart, that.thenpart) 375 && scan(tree.elsepart, that.elsepart); 376 } 377 378 @Override visitImport(JCImport tree)379 public void visitImport(JCImport tree) { 380 JCImport that = (JCImport) parameter; 381 result = tree.staticImport == that.staticImport && scan(tree.qualid, that.qualid); 382 } 383 384 @Override visitIndexed(JCArrayAccess tree)385 public void visitIndexed(JCArrayAccess tree) { 386 JCArrayAccess that = (JCArrayAccess) parameter; 387 result = scan(tree.indexed, that.indexed) && scan(tree.index, that.index); 388 } 389 390 @Override visitLabelled(JCLabeledStatement tree)391 public void visitLabelled(JCLabeledStatement tree) { 392 JCLabeledStatement that = (JCLabeledStatement) parameter; 393 result = tree.label == that.label && scan(tree.body, that.body); 394 } 395 396 @Override visitLambda(JCLambda tree)397 public void visitLambda(JCLambda tree) { 398 JCLambda that = (JCLambda) parameter; 399 result = 400 scan(tree.params, that.params) 401 && scan(tree.body, that.body) 402 && tree.paramKind == that.paramKind; 403 } 404 405 @Override visitLetExpr(LetExpr tree)406 public void visitLetExpr(LetExpr tree) { 407 LetExpr that = (LetExpr) parameter; 408 result = scan(tree.defs, that.defs) && scan(tree.expr, that.expr); 409 } 410 411 @Override visitLiteral(JCLiteral tree)412 public void visitLiteral(JCLiteral tree) { 413 JCLiteral that = (JCLiteral) parameter; 414 result = tree.typetag == that.typetag && Objects.equals(tree.value, that.value); 415 } 416 417 @Override visitMethodDef(JCMethodDecl tree)418 public void visitMethodDef(JCMethodDecl tree) { 419 JCMethodDecl that = (JCMethodDecl) parameter; 420 result = 421 scan(tree.mods, that.mods) 422 && tree.name == that.name 423 && scan(tree.restype, that.restype) 424 && scan(tree.typarams, that.typarams) 425 && scan(tree.recvparam, that.recvparam) 426 && scan(tree.params, that.params) 427 && scan(tree.thrown, that.thrown) 428 && scan(tree.body, that.body) 429 && scan(tree.defaultValue, that.defaultValue); 430 } 431 432 @Override visitModifiers(JCModifiers tree)433 public void visitModifiers(JCModifiers tree) { 434 JCModifiers that = (JCModifiers) parameter; 435 result = tree.flags == that.flags && scan(tree.annotations, that.annotations); 436 } 437 438 @Override visitModuleDef(JCModuleDecl tree)439 public void visitModuleDef(JCModuleDecl tree) { 440 JCModuleDecl that = (JCModuleDecl) parameter; 441 result = 442 scan(tree.mods, that.mods) 443 && scan(tree.qualId, that.qualId) 444 && scan(tree.directives, that.directives); 445 } 446 447 @Override visitNewArray(JCNewArray tree)448 public void visitNewArray(JCNewArray tree) { 449 JCNewArray that = (JCNewArray) parameter; 450 result = 451 scan(tree.elemtype, that.elemtype) 452 && scan(tree.dims, that.dims) 453 && scan(tree.annotations, that.annotations) 454 && scanDimAnnotations(tree.dimAnnotations, that.dimAnnotations) 455 && scan(tree.elems, that.elems); 456 } 457 458 @Override visitNewClass(JCNewClass tree)459 public void visitNewClass(JCNewClass tree) { 460 JCNewClass that = (JCNewClass) parameter; 461 result = 462 scan(tree.encl, that.encl) 463 && scan(tree.typeargs, that.typeargs) 464 && scan(tree.clazz, that.clazz) 465 && scan(tree.args, that.args) 466 && scan(tree.def, that.def) 467 && tree.constructor == that.constructor; 468 } 469 470 @Override visitOpens(JCOpens tree)471 public void visitOpens(JCOpens tree) { 472 JCOpens that = (JCOpens) parameter; 473 result = scan(tree.qualid, that.qualid) && scan(tree.moduleNames, that.moduleNames); 474 } 475 476 @Override visitPackageDef(JCPackageDecl tree)477 public void visitPackageDef(JCPackageDecl tree) { 478 JCPackageDecl that = (JCPackageDecl) parameter; 479 result = 480 scan(tree.annotations, that.annotations) 481 && scan(tree.pid, that.pid) 482 && tree.packge == that.packge; 483 } 484 485 @Override visitProvides(JCProvides tree)486 public void visitProvides(JCProvides tree) { 487 JCProvides that = (JCProvides) parameter; 488 result = scan(tree.serviceName, that.serviceName) && scan(tree.implNames, that.implNames); 489 } 490 491 @Override visitReference(JCMemberReference tree)492 public void visitReference(JCMemberReference tree) { 493 JCMemberReference that = (JCMemberReference) parameter; 494 result = 495 tree.mode == that.mode 496 && tree.kind == that.kind 497 && tree.name == that.name 498 && scan(tree.expr, that.expr) 499 && scan(tree.typeargs, that.typeargs); 500 } 501 502 @Override visitRequires(JCRequires tree)503 public void visitRequires(JCRequires tree) { 504 JCRequires that = (JCRequires) parameter; 505 result = 506 tree.isTransitive == that.isTransitive 507 && tree.isStaticPhase == that.isStaticPhase 508 && scan(tree.moduleName, that.moduleName); 509 } 510 511 @Override visitReturn(JCReturn tree)512 public void visitReturn(JCReturn tree) { 513 JCReturn that = (JCReturn) parameter; 514 result = scan(tree.expr, that.expr); 515 } 516 517 @Override visitSwitch(JCSwitch tree)518 public void visitSwitch(JCSwitch tree) { 519 JCSwitch that = (JCSwitch) parameter; 520 result = scan(tree.selector, that.selector) && scan(tree.cases, that.cases); 521 } 522 523 @Override visitSwitchExpression(JCSwitchExpression tree)524 public void visitSwitchExpression(JCSwitchExpression tree) { 525 JCSwitchExpression that = (JCSwitchExpression) parameter; 526 result = scan(tree.selector, that.selector) && scan(tree.cases, that.cases); 527 } 528 529 @Override visitSynchronized(JCSynchronized tree)530 public void visitSynchronized(JCSynchronized tree) { 531 JCSynchronized that = (JCSynchronized) parameter; 532 result = scan(tree.lock, that.lock) && scan(tree.body, that.body); 533 } 534 535 @Override visitThrow(JCThrow tree)536 public void visitThrow(JCThrow tree) { 537 JCThrow that = (JCThrow) parameter; 538 result = scan(tree.expr, that.expr); 539 } 540 541 @Override visitTopLevel(JCCompilationUnit tree)542 public void visitTopLevel(JCCompilationUnit tree) { 543 JCCompilationUnit that = (JCCompilationUnit) parameter; 544 result = 545 scan(tree.defs, that.defs) 546 && tree.modle == that.modle 547 && tree.packge == that.packge; 548 } 549 550 @Override visitTry(JCTry tree)551 public void visitTry(JCTry tree) { 552 JCTry that = (JCTry) parameter; 553 result = 554 scan(tree.body, that.body) 555 && scan(tree.catchers, that.catchers) 556 && scan(tree.finalizer, that.finalizer) 557 && scan(tree.resources, that.resources); 558 } 559 560 @Override visitTypeApply(JCTypeApply tree)561 public void visitTypeApply(JCTypeApply tree) { 562 JCTypeApply that = (JCTypeApply) parameter; 563 result = scan(tree.clazz, that.clazz) && scan(tree.arguments, that.arguments); 564 } 565 566 @Override visitTypeArray(JCArrayTypeTree tree)567 public void visitTypeArray(JCArrayTypeTree tree) { 568 JCArrayTypeTree that = (JCArrayTypeTree) parameter; 569 result = scan(tree.elemtype, that.elemtype); 570 } 571 572 @Override visitTypeBoundKind(TypeBoundKind tree)573 public void visitTypeBoundKind(TypeBoundKind tree) { 574 TypeBoundKind that = (TypeBoundKind) parameter; 575 result = tree.kind == that.kind; 576 } 577 578 @Override visitTypeCast(JCTypeCast tree)579 public void visitTypeCast(JCTypeCast tree) { 580 JCTypeCast that = (JCTypeCast) parameter; 581 result = scan(tree.clazz, that.clazz) && scan(tree.expr, that.expr); 582 } 583 584 @Override visitTypeIdent(JCPrimitiveTypeTree tree)585 public void visitTypeIdent(JCPrimitiveTypeTree tree) { 586 JCPrimitiveTypeTree that = (JCPrimitiveTypeTree) parameter; 587 result = tree.typetag == that.typetag; 588 } 589 590 @Override visitTypeIntersection(JCTypeIntersection tree)591 public void visitTypeIntersection(JCTypeIntersection tree) { 592 JCTypeIntersection that = (JCTypeIntersection) parameter; 593 result = scan(tree.bounds, that.bounds); 594 } 595 596 @Override visitTypeParameter(JCTypeParameter tree)597 public void visitTypeParameter(JCTypeParameter tree) { 598 JCTypeParameter that = (JCTypeParameter) parameter; 599 result = 600 tree.name == that.name 601 && scan(tree.bounds, that.bounds) 602 && scan(tree.annotations, that.annotations); 603 } 604 605 @Override visitTypeTest(JCInstanceOf tree)606 public void visitTypeTest(JCInstanceOf tree) { 607 JCInstanceOf that = (JCInstanceOf) parameter; 608 result = scan(tree.expr, that.expr) && scan(tree.pattern, that.pattern); 609 } 610 611 @Override visitTypeUnion(JCTypeUnion tree)612 public void visitTypeUnion(JCTypeUnion tree) { 613 JCTypeUnion that = (JCTypeUnion) parameter; 614 result = scan(tree.alternatives, that.alternatives); 615 } 616 617 @Override visitUnary(JCUnary tree)618 public void visitUnary(JCUnary tree) { 619 JCUnary that = (JCUnary) parameter; 620 result = scan(tree.arg, that.arg) && tree.operator == that.operator; 621 } 622 623 @Override visitUses(JCUses tree)624 public void visitUses(JCUses tree) { 625 JCUses that = (JCUses) parameter; 626 result = scan(tree.qualid, that.qualid); 627 } 628 629 @Override visitVarDef(JCVariableDecl tree)630 public void visitVarDef(JCVariableDecl tree) { 631 JCVariableDecl that = (JCVariableDecl) parameter; 632 result = 633 scan(tree.mods, that.mods) 634 && tree.name == that.name 635 && scan(tree.nameexpr, that.nameexpr) 636 && scan(tree.vartype, that.vartype) 637 && scan(tree.init, that.init); 638 if (!result) { 639 return; 640 } 641 equiv.put(tree.sym, that.sym); 642 } 643 644 @Override visitWhileLoop(JCWhileLoop tree)645 public void visitWhileLoop(JCWhileLoop tree) { 646 JCWhileLoop that = (JCWhileLoop) parameter; 647 result = scan(tree.cond, that.cond) && scan(tree.body, that.body); 648 } 649 650 @Override visitWildcard(JCWildcard tree)651 public void visitWildcard(JCWildcard tree) { 652 JCWildcard that = (JCWildcard) parameter; 653 result = scan(tree.kind, that.kind) && scan(tree.inner, that.inner); 654 } 655 } 656