001/* 002 * Copyright (c) 2012-2021 Institut National des Sciences Appliquées de Lyon (INSA Lyon) and others 003 * 004 * This program and the accompanying materials are made available under the 005 * terms of the Eclipse Public License 2.0 which is available at 006 * http://www.eclipse.org/legal/epl-2.0. 007 * 008 * SPDX-License-Identifier: EPL-2.0 009 */ 010 011package org.eclipse.golo.cli.command; 012 013import com.beust.jcommander.IParameterValidator; 014import com.beust.jcommander.Parameter; 015import com.beust.jcommander.ParameterException; 016import com.beust.jcommander.Parameters; 017import com.beust.jcommander.ParametersDelegate; 018import com.beust.jcommander.converters.FileConverter; 019import org.eclipse.golo.cli.command.spi.CliCommand; 020import org.eclipse.golo.compiler.GoloCompiler; 021import gololang.ir.GoloModule; 022import gololang.ir.IrTreeDumper; 023import org.eclipse.golo.compiler.parser.ASTCompilationUnit; 024import org.eclipse.golo.cli.GoloFilesManager; 025 026import java.io.File; 027import java.util.LinkedList; 028import java.util.List; 029import java.util.function.Consumer; 030 031import static gololang.Messages.*; 032 033@Parameters(commandNames = "diagnose", resourceBundle = "commands", commandDescriptionKey = "diagnose") 034public final class DiagnoseCommand implements CliCommand { 035 036 @Parameter(names = "--tool", hidden = true, descriptionKey = "diagnose.tool", validateWith = DiagnoseModeValidator.class) 037 String mode = "ir"; 038 039 @Parameter(names = "--stage", descriptionKey = "diagnose.stage", validateWith = DiagnoseStageValidator.class) 040 String stage = "refined"; 041 042 @Parameter(description = "source_files", converter = FileConverter.class) 043 List<File> files = new LinkedList<>(); 044 045 @ParametersDelegate 046 ClasspathOption classpath = new ClasspathOption(); 047 048 @Override 049 public void execute() throws Throwable { 050 if ("ast".equals(this.stage) && !"ast".equals(this.mode)) { 051 this.mode = "ast"; 052 } 053 if ("ast".equals(this.mode) && !"ast".equals(this.stage)) { 054 this.stage = "ast"; 055 } 056 GoloCompiler compiler = classpath.initGoloClassLoader().getCompiler(); 057 switch (this.mode) { 058 case "ast": 059 GoloFilesManager.goloFiles(this.files).forEach(dumpAST(compiler)); 060 break; 061 case "ir": 062 IrTreeDumper dumper = new IrTreeDumper(); 063 GoloFilesManager.goloFiles(this.files).forEach(dumpIR(compiler, dumper)); 064 break; 065 default: 066 throw new AssertionError("WTF?"); 067 } 068 } 069 070 private Consumer<File> dumpAST(GoloCompiler compiler) throws Throwable { 071 return wrappedAction(file -> { 072 compiler.resetExceptionBuilder(); 073 System.out.println(">>> AST: " + file.getAbsolutePath()); 074 ASTCompilationUnit ast = compiler.parse(file); 075 ast.dump("% "); 076 System.out.println(); 077 }); 078 } 079 080 private Consumer<File> dumpIR(GoloCompiler compiler, IrTreeDumper dumper) throws Throwable { 081 return wrappedAction(file -> { 082 compiler.resetExceptionBuilder(); 083 System.out.println(">>> IR: " + file.getAbsolutePath()); 084 GoloModule module = compiler.transform(compiler.parse(file)); 085 switch (this.stage) { 086 case "raw": 087 break; 088 case "expanded": 089 compiler.expand(module); 090 break; 091 case "refined": 092 compiler.expand(module); 093 compiler.refine(module); 094 break; 095 default: 096 break; 097 } 098 module.accept(dumper); 099 System.out.println(); 100 }); 101 } 102 103 public static final class DiagnoseModeValidator implements IParameterValidator { 104 105 @Override 106 public void validate(String name, String value) throws ParameterException { 107 warning(message("diagnose_tool_warning")); 108 switch (value) { 109 case "ast": 110 case "ir": 111 return; 112 default: 113 throw new ParameterException(message("diagnose_tool_error", "{ast, ir}")); 114 } 115 } 116 } 117 118 public static final class DiagnoseStageValidator implements IParameterValidator { 119 120 @Override 121 public void validate(String name, String value) throws ParameterException { 122 switch (value) { 123 case "ast": 124 case "raw": 125 case "expanded": 126 case "refined": 127 return; 128 default: 129 throw new ParameterException(message("diagnose_stage_error", "{ast, raw, expanded, refined}")); 130 } 131 } 132 } 133 134}