001/* 002 * Copyright (c) 2012-2017 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the Eclipse Public License v1.0 006 * which accompanies this distribution, and is available at 007 * http://www.eclipse.org/legal/epl-v10.html 008 */ 009 010package org.eclipse.golo.compiler.ir; 011 012public class IrTreeDumper implements GoloIrVisitor { 013 014 private int spacing = 0; 015 016 private void space() { 017 System.out.print("# "); 018 for (int i = 0; i < spacing; i++) { 019 System.out.print(" "); 020 } 021 } 022 023 private void incr() { 024 spacing = spacing + 2; 025 } 026 027 private void decr() { 028 spacing = spacing - 2; 029 } 030 031 @Override 032 public void visitModule(GoloModule module) { 033 space(); 034 System.out.println(module.getPackageAndClass()); 035 module.walk(this); 036 } 037 038 @Override 039 public void visitModuleImport(ModuleImport moduleImport) { 040 incr(); 041 space(); 042 System.out.println(" - " + moduleImport); 043 moduleImport.walk(this); 044 decr(); 045 } 046 047 @Override 048 public void visitNamedAugmentation(NamedAugmentation namedAugmentation) { 049 incr(); 050 space(); 051 System.out.println("Named Augmentation " + namedAugmentation.getName()); 052 namedAugmentation.walk(this); 053 decr(); 054 } 055 056 @Override 057 public void visitAugmentation(Augmentation augmentation) { 058 incr(); 059 space(); 060 System.out.println("Augmentation on " + augmentation.getTarget()); 061 if (augmentation.hasNames()) { 062 incr(); 063 for (String name : augmentation.getNames()) { 064 space(); 065 System.out.println("Named Augmentation " + name); 066 } 067 decr(); 068 } 069 augmentation.walk(this); 070 decr(); 071 } 072 073 @Override 074 public void visitStruct(Struct struct) { 075 incr(); 076 space(); 077 System.out.println("Struct " + struct.getPackageAndClass().className()); 078 space(); 079 System.out.println(" - target class = " + struct.getPackageAndClass()); 080 incr(); 081 space(); 082 System.out.println("Members: "); 083 struct.walk(this); 084 decr(); 085 decr(); 086 } 087 088 @Override 089 public void visitUnion(Union union) { 090 incr(); 091 space(); 092 System.out.println("Union " + union.getPackageAndClass().className()); 093 space(); 094 System.out.println(" - target class = " + union.getPackageAndClass()); 095 union.walk(this); 096 decr(); 097 } 098 099 @Override 100 public void visitUnionValue(UnionValue value) { 101 incr(); 102 space(); 103 System.out.println("Value " + value.getPackageAndClass().className()); 104 space(); 105 System.out.println(" - target class = " + value.getPackageAndClass()); 106 if (value.hasMembers()) { 107 space(); 108 System.out.println(" - members = " + value.getMembers()); 109 } 110 decr(); 111 } 112 113 @Override 114 public void visitFunction(GoloFunction function) { 115 incr(); 116 space(); 117 System.out.print("Function " + function.getName() + " = "); 118 visitFunctionDefinition(function); 119 decr(); 120 } 121 122 private void visitFunctionDefinition(GoloFunction function) { 123 System.out.print("|"); 124 boolean first = true; 125 for (String param : function.getParameterNames()) { 126 if (first) { 127 first = false; 128 } else { 129 System.out.print(", "); 130 } 131 System.out.print(param); 132 } 133 System.out.print("|"); 134 if (function.isVarargs()) { 135 System.out.print(" (varargs)"); 136 } 137 if (function.isSynthetic()) { 138 System.out.print(" (synthetic, " + function.getSyntheticParameterCount() + " synthetic parameters)"); 139 if (function.getSyntheticSelfName() != null) { 140 System.out.print(" (selfname: " + function.getSyntheticSelfName() + ")"); 141 } 142 } 143 System.out.println(); 144 function.walk(this); 145 } 146 147 @Override 148 public void visitDecorator(Decorator decorator) { 149 incr(); 150 space(); 151 System.out.println("@Decorator"); 152 decorator.getExpressionStatement().accept(this); 153 decr(); 154 } 155 156 @Override 157 public void visitBlock(Block block) { 158 if (block.isEmpty()) { return; } 159 incr(); 160 space(); 161 System.out.println("Block"); 162 block.walk(this); 163 decr(); 164 } 165 166 @Override 167 public void visitLocalReference(LocalReference ref) { 168 incr(); 169 space(); 170 System.out.println(" - " + ref); 171 decr(); 172 } 173 174 @Override 175 public void visitConstantStatement(ConstantStatement constantStatement) { 176 incr(); 177 space(); 178 System.out.println("Constant = " + constantStatement.getValue()); 179 decr(); 180 } 181 182 @Override 183 public void visitReturnStatement(ReturnStatement returnStatement) { 184 incr(); 185 space(); 186 System.out.println("Return"); 187 returnStatement.walk(this); 188 decr(); 189 } 190 191 @Override 192 public void visitFunctionInvocation(FunctionInvocation functionInvocation) { 193 incr(); 194 space(); 195 System.out.println("Function call: " + functionInvocation.getName() 196 + ", on reference? -> " + functionInvocation.isOnReference() 197 + ", on module state? -> " + functionInvocation.isOnModuleState() 198 + ", anonymous? -> " + functionInvocation.isAnonymous() 199 + ", named arguments? -> " + functionInvocation.usesNamedArguments()); 200 201 functionInvocation.walk(this); 202 decr(); 203 } 204 205 @Override 206 public void visitAssignmentStatement(AssignmentStatement assignmentStatement) { 207 incr(); 208 space(); 209 System.out.print("Assignment: " + assignmentStatement.getLocalReference()); 210 System.out.println(assignmentStatement.isDeclaring() ? " (declaring)" : ""); 211 assignmentStatement.walk(this); 212 decr(); 213 } 214 215 @Override 216 public void visitDestructuringAssignment(DestructuringAssignment assignment) { 217 incr(); 218 space(); 219 System.out.format( 220 "Destructuring assignement: {declaring=%s, varargs=%s}%n", 221 assignment.isDeclaring(), 222 assignment.isVarargs()); 223 incr(); 224 for (LocalReference ref : assignment.getReferences()) { 225 space(); 226 System.out.println("- " + ref); 227 } 228 decr(); 229 assignment.getExpression().accept(this); 230 decr(); 231 } 232 233 @Override 234 public void visitReferenceLookup(ReferenceLookup referenceLookup) { 235 incr(); 236 space(); 237 System.out.println("Reference lookup: " + referenceLookup.getName()); 238 decr(); 239 } 240 241 @Override 242 public void visitConditionalBranching(ConditionalBranching conditionalBranching) { 243 incr(); 244 space(); 245 System.out.println("Conditional"); 246 conditionalBranching.getCondition().accept(this); 247 conditionalBranching.getTrueBlock().accept(this); 248 if (conditionalBranching.hasFalseBlock()) { 249 conditionalBranching.getFalseBlock().accept(this); 250 } else if (conditionalBranching.hasElseConditionalBranching()) { 251 conditionalBranching.getElseConditionalBranching().accept(this); 252 } 253 decr(); 254 } 255 256 @Override 257 public void visitCaseStatement(CaseStatement caseStatement) { 258 incr(); 259 space(); 260 System.out.println("Case"); 261 incr(); 262 for (WhenClause<Block> c : caseStatement.getClauses()) { 263 space(); 264 System.out.println("When"); 265 incr(); 266 c.condition().accept(this); 267 c.action().accept(this); 268 decr(); 269 } 270 space(); 271 System.out.println("Otherwise"); 272 caseStatement.getOtherwise().accept(this); 273 decr(); 274 } 275 276 @Override 277 public void visitMatchExpression(MatchExpression matchExpression) { 278 incr(); 279 space(); 280 System.out.println("Match"); 281 incr(); 282 for (WhenClause<?> c : matchExpression.getClauses()) { 283 c.accept(this); 284 } 285 space(); 286 System.out.println("Otherwise"); 287 matchExpression.getOtherwise().accept(this); 288 decr(); 289 } 290 291 @Override 292 public void visitWhenClause(WhenClause<?> whenClause) { 293 space(); 294 System.out.println("When"); 295 incr(); 296 whenClause.walk(this); 297 decr(); 298 } 299 300 @Override 301 public void visitBinaryOperation(BinaryOperation binaryOperation) { 302 incr(); 303 space(); 304 System.out.println("Binary operator: " + binaryOperation.getType()); 305 binaryOperation.walk(this); 306 decr(); 307 } 308 309 @Override 310 public void visitUnaryOperation(UnaryOperation unaryOperation) { 311 incr(); 312 space(); 313 System.out.println("Unary operator: " + unaryOperation.getType()); 314 unaryOperation.getExpressionStatement().accept(this); 315 decr(); 316 } 317 318 @Override 319 public void visitLoopStatement(LoopStatement loopStatement) { 320 incr(); 321 space(); 322 System.out.println("Loop"); 323 if (loopStatement.hasInitStatement()) { 324 loopStatement.getInitStatement().accept(this); 325 } 326 loopStatement.getConditionStatement().accept(this); 327 loopStatement.getBlock().accept(this); 328 if (loopStatement.hasPostStatement()) { 329 loopStatement.getPostStatement().accept(this); 330 } 331 decr(); 332 } 333 334 @Override 335 public void visitForEachLoopStatement(ForEachLoopStatement foreachStatement) { 336 incr(); 337 space(); 338 System.out.println("Foreach"); 339 incr(); 340 for (LocalReference ref : foreachStatement.getReferences()) { 341 ref.accept(this); 342 } 343 foreachStatement.getIterable().accept(this); 344 if (foreachStatement.hasWhenClause()) { 345 space(); 346 System.out.println("When:"); 347 foreachStatement.getWhenClause().accept(this); 348 } 349 foreachStatement.getBlock().accept(this); 350 decr(); 351 decr(); 352 } 353 354 @Override 355 public void visitMethodInvocation(MethodInvocation methodInvocation) { 356 incr(); 357 space(); 358 System.out.format("Method invocation: %s, null safe? -> %s%n", 359 methodInvocation.getName(), 360 methodInvocation.isNullSafeGuarded()); 361 methodInvocation.walk(this); 362 decr(); 363 } 364 365 @Override 366 public void visitThrowStatement(ThrowStatement throwStatement) { 367 incr(); 368 space(); 369 System.out.println("Throw"); 370 throwStatement.getExpressionStatement().accept(this); 371 decr(); 372 } 373 374 @Override 375 public void visitTryCatchFinally(TryCatchFinally tryCatchFinally) { 376 incr(); 377 space(); 378 System.out.println("Try"); 379 tryCatchFinally.getTryBlock().accept(this); 380 if (tryCatchFinally.hasCatchBlock()) { 381 space(); 382 System.out.println("Catch: " + tryCatchFinally.getExceptionId()); 383 tryCatchFinally.getCatchBlock().accept(this); 384 } 385 if (tryCatchFinally.hasFinallyBlock()) { 386 space(); 387 System.out.println("Finally"); 388 tryCatchFinally.getFinallyBlock().accept(this); 389 } 390 decr(); 391 } 392 393 @Override 394 public void visitClosureReference(ClosureReference closureReference) { 395 GoloFunction target = closureReference.getTarget(); 396 incr(); 397 space(); 398 if (target.isAnonymous()) { 399 System.out.print("Closure: "); 400 incr(); 401 visitFunctionDefinition(target); 402 decr(); 403 } else { 404 System.out.printf( 405 "Closure reference: %s, regular arguments at index %d%n", 406 target.getName(), 407 target.getSyntheticParameterCount()); 408 incr(); 409 for (String refName : closureReference.getCapturedReferenceNames()) { 410 space(); 411 System.out.println("- capture: " + refName); 412 } 413 decr(); 414 } 415 decr(); 416 } 417 418 @Override 419 public void visitLoopBreakFlowStatement(LoopBreakFlowStatement loopBreakFlowStatement) { 420 incr(); 421 space(); 422 System.out.println("Loop break flow: " + loopBreakFlowStatement.getType().name()); 423 decr(); 424 } 425 426 @Override 427 public void visitCollectionLiteral(CollectionLiteral collectionLiteral) { 428 incr(); 429 space(); 430 System.out.println("Collection literal of type: " + collectionLiteral.getType()); 431 for (ExpressionStatement statement : collectionLiteral.getExpressions()) { 432 statement.accept(this); 433 } 434 decr(); 435 } 436 437 @Override 438 public void visitCollectionComprehension(CollectionComprehension collectionComprehension) { 439 incr(); 440 space(); 441 System.out.println("Collection comprehension of type: " + collectionComprehension.getType()); 442 incr(); 443 space(); 444 System.out.println("Expression: "); 445 collectionComprehension.getExpression().accept(this); 446 space(); 447 System.out.println("Comprehension: "); 448 for (Block b : collectionComprehension.getLoopBlocks()) { 449 b.accept(this); 450 } 451 decr(); 452 decr(); 453 } 454 455 @Override 456 public void visitNamedArgument(NamedArgument namedArgument) { 457 incr(); 458 space(); 459 System.out.println("Named argument: " + namedArgument.getName()); 460 namedArgument.getExpression().accept(this); 461 decr(); 462 } 463 464 @Override 465 public void visitMember(Member member) { 466 space(); 467 System.out.print(" - "); 468 System.out.print(member.getName()); 469 System.out.println(); 470 } 471}