Coverage Summary for Class: SolidityCompiler (org.ethereum.solidity.compiler)
Class |
Method, %
|
Line, %
|
SolidityCompiler |
0%
(0/4)
|
0%
(0/30)
|
SolidityCompiler$Options |
0%
(0/4)
|
0%
(0/9)
|
SolidityCompiler$ParallelReader |
0%
(0/4)
|
0%
(0/21)
|
SolidityCompiler$Result |
0%
(0/2)
|
0%
(0/4)
|
Total |
0%
(0/14)
|
0%
(0/64)
|
1 /*
2 * This file is part of RskJ
3 * Copyright (C) 2017 RSK Labs Ltd.
4 * (derived from ethereumJ library, Copyright (c) 2016 <ether.camp>)
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 package org.ethereum.solidity.compiler;
21
22 import org.ethereum.config.SystemProperties;
23 import org.slf4j.LoggerFactory;
24
25 import java.io.*;
26 import java.util.ArrayList;
27 import java.util.Arrays;
28 import java.util.List;
29 import java.util.stream.Collectors;
30
31 import static org.apache.commons.lang3.StringUtils.isNotBlank;
32
33 // TODO(techdebt) this class is not used in production, should be removed
34 public class SolidityCompiler {
35 private static final org.slf4j.Logger logger = LoggerFactory.getLogger("soliditycompiler");
36
37 private Solc solc;
38
39 public SolidityCompiler(SystemProperties config) {
40 solc = new Solc(config);
41 }
42
43 public enum Options {
44 AST("ast"),
45 BIN("bin"),
46 INTERFACE("interface"),
47 ABI("abi");
48
49 private String name;
50
51 Options(String name) {
52 this.name = name;
53 }
54
55 public String getName() {
56 return name;
57 }
58
59 @Override
60 public String toString() {
61 return name;
62 }
63 }
64
65 public static class Result {
66 public String errors;
67 public String output;
68
69 public Result(String errors, String output) {
70 this.errors = errors;
71 this.output = output;
72 }
73
74 public boolean isFailed() {
75 return isNotBlank(errors);
76 }
77 }
78
79 private static class ParallelReader extends Thread {
80
81 private InputStream stream;
82 private StringBuilder content = new StringBuilder();
83
84 ParallelReader(InputStream stream) {
85 this.stream = stream;
86 }
87
88 public String getContent() {
89 return getContent(true);
90 }
91
92 public synchronized String getContent(boolean waitForComplete) {
93 if (waitForComplete) {
94 while(stream != null) {
95 try {
96 wait();
97 } catch (InterruptedException e) {
98 throw new RuntimeException(e);
99 }
100 }
101 }
102 return content.toString();
103 }
104
105 public void run() {
106 try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) {
107 String line;
108 while ((line = reader.readLine()) != null) {
109 content.append(line).append("\n");
110 }
111 } catch (IOException ioe) {
112 logger.error("Error running solidity compiler", ioe);
113 } finally {
114 synchronized (this) {
115 stream = null;
116 notifyAll();
117 }
118 }
119 }
120 }
121
122 public Result compile(byte[] source, boolean combinedJson, Options... options) throws IOException {
123 List<String> commandParts = new ArrayList<>();
124 commandParts.add(solc.getExecutable().getCanonicalPath());
125 if (combinedJson) {
126 commandParts.add("--combined-json");
127 String combined = Arrays.stream(options).map(Options::toString).collect(Collectors.joining(","));
128 commandParts.add(combined);
129 } else {
130 for (Options option : options) {
131 commandParts.add("--" + option.getName());
132 }
133 }
134
135 ProcessBuilder processBuilder = new ProcessBuilder(commandParts)
136 .directory(solc.getExecutable().getParentFile());
137 processBuilder.environment().put("LD_LIBRARY_PATH",
138 solc.getExecutable().getParentFile().getCanonicalPath());
139
140 Process process = processBuilder.start();
141
142 try (BufferedOutputStream stream = new BufferedOutputStream(process.getOutputStream())) {
143 stream.write(source);
144 }
145
146 ParallelReader error = new ParallelReader(process.getErrorStream());
147 ParallelReader output = new ParallelReader(process.getInputStream());
148 error.start();
149 output.start();
150
151 try {
152 process.waitFor();
153 } catch (InterruptedException e) {
154 throw new RuntimeException(e);
155 }
156
157 return new Result(error.getContent(), output.getContent());
158 }
159 }