C: add option to generate shorter output file names to workaround msvc bug

This commit is contained in:
Alexey Andreev 2021-12-10 18:51:12 +03:00
parent 2f7f4e7782
commit 1fa48560c6
18 changed files with 333 additions and 156 deletions

View File

@ -1,35 +1,33 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="build-teavm-fast" type="MavenRunConfiguration" factoryName="Maven"> <configuration default="false" name="build-teavm-fast" type="MavenRunConfiguration" factoryName="Maven">
<MavenRunConfigurationSettings> <MavenSettings>
<option name="alwaysUpdateSnapshots" value="false" /> <option name="myGeneralSettings" />
<option name="checksumPolicy" /> <option name="myRunnerSettings" />
<option name="commandLine" value="-e install -DskipTests -Dteavm.build.all=false -Pwith-cli -Dmaven.javadoc.skip=true" /> <option name="myRunnerParameters">
<option name="environment"> <MavenRunnerParameters>
<map /> <option name="profiles">
<set />
</option>
<option name="goals">
<list>
<option value="-e" />
<option value="install" />
<option value="-DskipTests" />
<option value="-Dteavm.build.all=false" />
<option value="-Pwith-cli" />
<option value="-Dmaven.javadoc.skip=true" />
<option value="-T4" />
</list>
</option>
<option name="pomFileName" />
<option name="profilesMap">
<map />
</option>
<option name="resolveToWorkspace" value="false" />
<option name="workingDirPath" value="$PROJECT_DIR$" />
</MavenRunnerParameters>
</option> </option>
<option name="failureBehavior" /> </MavenSettings>
<option name="jreName" />
<option name="localRepository" />
<option name="mavenHome" value="Bundled (Maven 3)" />
<option name="mavenProperties">
<map />
</option>
<option name="nonRecursive" value="false" />
<option name="outputLevel" />
<option name="passParentEnvs" value="true" />
<option name="printErrorStackTraces" value="false" />
<option name="profilesMap">
<map />
</option>
<option name="resolveToWorkspace" value="false" />
<option name="skipTests" value="false" />
<option name="threads" value="4" />
<option name="usePluginRegistry" value="false" />
<option name="userSettings" />
<option name="vmOptions" />
<option name="workOffline" value="false" />
<option name="workingDirectory" value="$PROJECT_DIR$" />
</MavenRunConfigurationSettings>
<method v="2" /> <method v="2" />
</configuration> </configuration>
</component> </component>

View File

@ -41,9 +41,11 @@ import org.teavm.backend.c.generate.ClassGenerationContext;
import org.teavm.backend.c.generate.ClassGenerator; import org.teavm.backend.c.generate.ClassGenerator;
import org.teavm.backend.c.generate.CodeGenerationVisitor; import org.teavm.backend.c.generate.CodeGenerationVisitor;
import org.teavm.backend.c.generate.CodeWriter; import org.teavm.backend.c.generate.CodeWriter;
import org.teavm.backend.c.generate.FileNameProvider;
import org.teavm.backend.c.generate.GenerationContext; import org.teavm.backend.c.generate.GenerationContext;
import org.teavm.backend.c.generate.IncludeManager; import org.teavm.backend.c.generate.IncludeManager;
import org.teavm.backend.c.generate.OutputFileUtil; import org.teavm.backend.c.generate.OutputFileUtil;
import org.teavm.backend.c.generate.SimpleFileNameProvider;
import org.teavm.backend.c.generate.SimpleIncludeManager; import org.teavm.backend.c.generate.SimpleIncludeManager;
import org.teavm.backend.c.generate.SimpleStringPool; import org.teavm.backend.c.generate.SimpleStringPool;
import org.teavm.backend.c.generate.StringPoolGenerator; import org.teavm.backend.c.generate.StringPoolGenerator;
@ -154,6 +156,7 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
private TeaVMTargetController controller; private TeaVMTargetController controller;
private NameProvider rawNameProvider; private NameProvider rawNameProvider;
private FileNameProvider fileNames = new SimpleFileNameProvider();
private ClassInitializerEliminator classInitializerEliminator; private ClassInitializerEliminator classInitializerEliminator;
private ClassInitializerTransformer classInitializerTransformer; private ClassInitializerTransformer classInitializerTransformer;
private ShadowStackTransformer shadowStackTransformer; private ShadowStackTransformer shadowStackTransformer;
@ -214,6 +217,10 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
this.obfuscated = obfuscated; this.obfuscated = obfuscated;
} }
public void setFileNames(FileNameProvider fileNames) {
this.fileNames = fileNames;
}
@Override @Override
public List<ClassHolderTransformer> getTransformers() { public List<ClassHolderTransformer> getTransformers() {
List<ClassHolderTransformer> transformers = new ArrayList<>(); List<ClassHolderTransformer> transformers = new ArrayList<>();
@ -402,8 +409,8 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
boolean vmAssertions = Boolean.parseBoolean(System.getProperty("teavm.c.vmAssertions", "false")); boolean vmAssertions = Boolean.parseBoolean(System.getProperty("teavm.c.vmAssertions", "false"));
boolean gcStats = Boolean.parseBoolean(System.getProperty("teavm.c.gcStats", "false")); boolean gcStats = Boolean.parseBoolean(System.getProperty("teavm.c.gcStats", "false"));
GenerationContext context = new GenerationContext(vtableProvider, characteristics, GenerationContext context = new GenerationContext(vtableProvider, characteristics,
controller.getDependencyInfo(), stringPool, nameProvider, controller.getDiagnostics(), classes, controller.getDependencyInfo(), stringPool, nameProvider, fileNames,
intrinsics, generators, asyncMethods::contains, buildTarget, controller.getDiagnostics(), classes, intrinsics, generators, asyncMethods::contains, buildTarget,
controller.getClassInitializerInfo(), incremental, longjmpUsed, controller.getClassInitializerInfo(), incremental, longjmpUsed,
vmAssertions, vmAssertions || heapDump, obfuscated); vmAssertions, vmAssertions || heapDump, obfuscated);
@ -497,7 +504,7 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
if (cls != null) { if (cls != null) {
classGenerator.generateClass(writer, headerWriter, cls); classGenerator.generateClass(writer, headerWriter, cls);
} }
String name = ClassGenerator.fileName(className); String name = fileNames.fileName(className);
OutputFileUtil.write(writer, name + ".c", buildTarget); OutputFileUtil.write(writer, name + ".c", buildTarget);
OutputFileUtil.write(headerWriter, name + ".h", buildTarget); OutputFileUtil.write(headerWriter, name + ".h", buildTarget);
if (incremental) { if (incremental) {
@ -512,7 +519,7 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
BufferedCodeWriter writer = new BufferedCodeWriter(false); BufferedCodeWriter writer = new BufferedCodeWriter(false);
BufferedCodeWriter headerWriter = new BufferedCodeWriter(false); BufferedCodeWriter headerWriter = new BufferedCodeWriter(false);
classGenerator.generateType(writer, headerWriter, type); classGenerator.generateType(writer, headerWriter, type);
String name = ClassGenerator.fileName(type); String name = fileNames.fileName(type);
OutputFileUtil.write(writer, name + ".c", buildTarget); OutputFileUtil.write(writer, name + ".c", buildTarget);
OutputFileUtil.write(headerWriter, name + ".h", buildTarget); OutputFileUtil.write(headerWriter, name + ".h", buildTarget);
if (incremental) { if (incremental) {
@ -525,7 +532,7 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
Collection<? extends String> classNames) throws IOException { Collection<? extends String> classNames) throws IOException {
BufferedCodeWriter writer = new BufferedCodeWriter(false); BufferedCodeWriter writer = new BufferedCodeWriter(false);
IncludeManager includes = new SimpleIncludeManager(writer); IncludeManager includes = new SimpleIncludeManager(context.getFileNames(), writer);
includes.init("callsites.c"); includes.init("callsites.c");
if (!incremental) { if (!incremental) {
@ -600,7 +607,7 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
private void generateStrings(BuildTarget buildTarget, GenerationContext context) throws IOException { private void generateStrings(BuildTarget buildTarget, GenerationContext context) throws IOException {
BufferedCodeWriter writer = new BufferedCodeWriter(false); BufferedCodeWriter writer = new BufferedCodeWriter(false);
IncludeManager includes = new SimpleIncludeManager(writer); IncludeManager includes = new SimpleIncludeManager(context.getFileNames(), writer);
includes.init("strings.c"); includes.init("strings.c");
BufferedCodeWriter headerWriter = new BufferedCodeWriter(false); BufferedCodeWriter headerWriter = new BufferedCodeWriter(false);
@ -664,7 +671,7 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
} }
private void generateSpecialFunctions(GenerationContext context, CodeWriter writer) { private void generateSpecialFunctions(GenerationContext context, CodeWriter writer) {
IncludeManager includes = new SimpleIncludeManager(writer); IncludeManager includes = new SimpleIncludeManager(context.getFileNames(), writer);
includes.init("special.c"); includes.init("special.c");
includes.includePath("core.h"); includes.includePath("core.h");
includes.includePath("string.h"); includes.includePath("string.h");
@ -731,7 +738,7 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
private void generateMainFile(GenerationContext context, ListableClassHolderSource classes, private void generateMainFile(GenerationContext context, ListableClassHolderSource classes,
List<? extends ValueType> types, BuildTarget buildTarget) throws IOException { List<? extends ValueType> types, BuildTarget buildTarget) throws IOException {
BufferedCodeWriter writer = new BufferedCodeWriter(false); BufferedCodeWriter writer = new BufferedCodeWriter(false);
IncludeManager includes = new SimpleIncludeManager(writer); IncludeManager includes = new SimpleIncludeManager(fileNames, writer);
includes.init("main.c"); includes.init("main.c");
includes.includePath("runtime.h"); includes.includePath("runtime.h");
includes.includePath("strings.h"); includes.includePath("strings.h");
@ -750,7 +757,7 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
writer.println("#define __USE_XOPEN"); writer.println("#define __USE_XOPEN");
writer.println("#define _GNU_SOURCE"); writer.println("#define _GNU_SOURCE");
IncludeManager includes = new SimpleIncludeManager(writer); IncludeManager includes = new SimpleIncludeManager(fileNames, writer);
includes.init("all.c"); includes.init("all.c");
for (String file : allFiles) { for (String file : allFiles) {
includes.includePath(file); includes.includePath(file);
@ -787,10 +794,10 @@ public class CTarget implements TeaVMTarget, TeaVMCHost {
files.add("virtcall.c"); files.add("virtcall.c");
for (String className : classes.getClassNames()) { for (String className : classes.getClassNames()) {
files.add(ClassGenerator.fileName(className) + ".c"); files.add(fileNames.fileName(className) + ".c");
} }
for (ValueType type : types) { for (ValueType type : types) {
files.add(ClassGenerator.fileName(type) + ".c"); files.add(fileNames.fileName(type) + ".c");
} }
files.add("main.c"); files.add("main.c");

View File

@ -208,7 +208,7 @@ public class ClassGenerator {
public void generateClass(CodeWriter writer, CodeWriter headerWriter, ClassHolder cls) { public void generateClass(CodeWriter writer, CodeWriter headerWriter, ClassHolder cls) {
ValueType type = ValueType.object(cls.getName()); ValueType type = ValueType.object(cls.getName());
init(writer, headerWriter, fileName(cls.getName()), type); init(writer, headerWriter, context.getFileNames().fileName(cls.getName()), type);
generateStringPoolDecl(type); generateStringPoolDecl(type);
generateClassStructure(cls); generateClassStructure(cls);
@ -228,7 +228,7 @@ public class ClassGenerator {
} }
public void generateType(CodeWriter writer, CodeWriter headerWriter, ValueType type) { public void generateType(CodeWriter writer, CodeWriter headerWriter, ValueType type) {
init(writer, headerWriter, fileName(type), type); init(writer, headerWriter, context.getFileNames().fileName(type), type);
generateStringPoolDecl(type); generateStringPoolDecl(type);
includes.includeType(type); includes.includeType(type);
generateVirtualTable(type); generateVirtualTable(type);
@ -239,14 +239,14 @@ public class ClassGenerator {
staticGcRoots = null; staticGcRoots = null;
classLayout = null; classLayout = null;
includes = new SimpleIncludeManager(writer); includes = new SimpleIncludeManager(context.getFileNames(), writer);
includes.init(fileName + ".c"); includes.init(fileName + ".c");
prologueWriter = writer.fragment(); prologueWriter = writer.fragment();
codeWriter = writer.fragment(); codeWriter = writer.fragment();
this.headerWriter = headerWriter; this.headerWriter = headerWriter;
headerWriter.println("#pragma once"); headerWriter.println("#pragma once");
headerIncludes = new SimpleIncludeManager(headerWriter); headerIncludes = new SimpleIncludeManager(context.getFileNames(), headerWriter);
headerIncludes.init(fileName + ".h"); headerIncludes.init(fileName + ".h");
headerIncludes.includePath("runtime.h"); headerIncludes.includePath("runtime.h");
@ -1438,103 +1438,4 @@ public class ClassGenerator {
break; break;
} }
} }
public static String fileName(ValueType type) {
StringBuilder sb = new StringBuilder();
fileNameRec(type, sb);
return sb.toString();
}
private static void fileNameRec(ValueType type, StringBuilder sb) {
if (type instanceof ValueType.Object) {
sb.append("classes/");
escape(((ValueType.Object) type).getClassName(), sb);
} else if (type instanceof ValueType.Array) {
sb.append("arrays/");
fileNameRec(((ValueType.Array) type).getItemType(), sb);
} else if (type instanceof ValueType.Primitive) {
sb.append("primitives/");
switch (((ValueType.Primitive) type).getKind()) {
case BOOLEAN:
sb.append("boolean");
break;
case BYTE:
sb.append("byte");
break;
case SHORT:
sb.append("short");
break;
case CHARACTER:
sb.append("char");
break;
case INTEGER:
sb.append("int");
break;
case LONG:
sb.append("long");
break;
case FLOAT:
sb.append("float");
break;
case DOUBLE:
sb.append("double");
break;
}
} else if (type == ValueType.VOID) {
sb.append("primitives/void");
}
}
public static String fileName(String className) {
StringBuilder sb = new StringBuilder("classes/");
escape(className, sb);
return sb.toString();
}
static void escape(String className, StringBuilder sb) {
for (int i = 0; i < className.length(); ++i) {
char c = className.charAt(i);
switch (c) {
case '.':
sb.append('/');
break;
case '@':
sb.append("@@");
break;
case '/':
sb.append("@s");
break;
case '\\':
sb.append("@b");
break;
case ':':
sb.append("@c");
break;
case ';':
sb.append("@e");
break;
case '*':
sb.append("@m");
break;
case '"':
sb.append("@q");
break;
case '<':
sb.append("@l");
break;
case '>':
sb.append("@g");
break;
case '|':
sb.append("@p");
break;
case '$':
sb.append("@d");
break;
default:
sb.append(c);
break;
}
}
}
} }

View File

@ -1565,9 +1565,7 @@ public class CodeGenerationVisitor implements ExprVisitor, StatementVisitor {
@Override @Override
public String escapeFileName(String name) { public String escapeFileName(String name) {
StringBuilder sb = new StringBuilder(); return context.getFileNames().escapeName(name);
ClassGenerator.escape(name, sb);
return sb.toString();
} }
@Override @Override

View File

@ -0,0 +1,26 @@
/*
* Copyright 2021 konso.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.backend.c.generate;
import org.teavm.model.ValueType;
public interface FileNameProvider {
String fileName(String className);
String fileName(ValueType type);
String escapeName(String name);
}

View File

@ -38,6 +38,7 @@ public class GenerationContext {
private DependencyInfo dependencies; private DependencyInfo dependencies;
private StringPool stringPool; private StringPool stringPool;
private NameProvider names; private NameProvider names;
private FileNameProvider fileNames;
private Diagnostics diagnostics; private Diagnostics diagnostics;
private ClassReaderSource classSource; private ClassReaderSource classSource;
private List<Intrinsic> intrinsics; private List<Intrinsic> intrinsics;
@ -53,9 +54,9 @@ public class GenerationContext {
private boolean obfuscated; private boolean obfuscated;
public GenerationContext(VirtualTableProvider virtualTableProvider, Characteristics characteristics, public GenerationContext(VirtualTableProvider virtualTableProvider, Characteristics characteristics,
DependencyInfo dependencies, StringPool stringPool, NameProvider names, Diagnostics diagnostics, DependencyInfo dependencies, StringPool stringPool, NameProvider names, FileNameProvider fileNames,
ClassReaderSource classSource, List<Intrinsic> intrinsics, List<Generator> generators, Diagnostics diagnostics, ClassReaderSource classSource, List<Intrinsic> intrinsics,
Predicate<MethodReference> asyncMethods, BuildTarget buildTarget, List<Generator> generators, Predicate<MethodReference> asyncMethods, BuildTarget buildTarget,
ClassInitializerInfo classInitializerInfo, boolean incremental, boolean longjmp, boolean vmAssertions, ClassInitializerInfo classInitializerInfo, boolean incremental, boolean longjmp, boolean vmAssertions,
boolean heapDump, boolean obfuscated) { boolean heapDump, boolean obfuscated) {
this.virtualTableProvider = virtualTableProvider; this.virtualTableProvider = virtualTableProvider;
@ -63,6 +64,7 @@ public class GenerationContext {
this.dependencies = dependencies; this.dependencies = dependencies;
this.stringPool = stringPool; this.stringPool = stringPool;
this.names = names; this.names = names;
this.fileNames = fileNames;
this.diagnostics = diagnostics; this.diagnostics = diagnostics;
this.classSource = classSource; this.classSource = classSource;
this.intrinsics = new ArrayList<>(intrinsics); this.intrinsics = new ArrayList<>(intrinsics);
@ -105,6 +107,10 @@ public class GenerationContext {
return names; return names;
} }
public FileNameProvider getFileNames() {
return fileNames;
}
public Diagnostics getDiagnostics() { public Diagnostics getDiagnostics() {
return diagnostics; return diagnostics;
} }

View File

@ -121,7 +121,7 @@ class GeneratorContextImpl implements GeneratorContext {
} }
private FileGenerator createFile(BufferedCodeWriter writer, String path) { private FileGenerator createFile(BufferedCodeWriter writer, String path) {
IncludeManager includes = new SimpleIncludeManager(writer); IncludeManager includes = new SimpleIncludeManager(context.getFileNames(), writer);
includes.init(path); includes.init(path);
FileGeneratorImpl generator = new FileGeneratorImpl(path, writer, includes); FileGeneratorImpl generator = new FileGeneratorImpl(path, writer, includes);
fileGenerators.add(generator); fileGenerators.add(generator);
@ -130,9 +130,7 @@ class GeneratorContextImpl implements GeneratorContext {
@Override @Override
public String escapeFileName(String name) { public String escapeFileName(String name) {
StringBuilder sb = new StringBuilder(); return context.getFileNames().escapeName(name);
ClassGenerator.escape(name, sb);
return sb.toString();
} }
@Override @Override

View File

@ -20,11 +20,16 @@ import java.util.Set;
import org.teavm.model.ValueType; import org.teavm.model.ValueType;
public abstract class IncludeManager { public abstract class IncludeManager {
private FileNameProvider fileNames;
private String currentFileName; private String currentFileName;
private Set<String> includedFiles = new HashSet<>(); private Set<String> includedFiles = new HashSet<>();
private Set<String> includedClasses = new HashSet<>(); private Set<String> includedClasses = new HashSet<>();
private Set<ValueType> includedTypes = new HashSet<>(); private Set<ValueType> includedTypes = new HashSet<>();
public IncludeManager(FileNameProvider fileNames) {
this.fileNames = fileNames;
}
public void init(String currentFileName) { public void init(String currentFileName) {
this.currentFileName = currentFileName; this.currentFileName = currentFileName;
includedFiles.clear(); includedFiles.clear();
@ -63,14 +68,14 @@ public abstract class IncludeManager {
if (!includedClasses.add(className)) { if (!includedClasses.add(className)) {
return; return;
} }
includePath(ClassGenerator.fileName(className) + ".h"); includePath(fileNames.fileName(className) + ".h");
} }
public void includeType(ValueType type) { public void includeType(ValueType type) {
if (!includedTypes.add(type)) { if (!includedTypes.add(type)) {
return; return;
} }
includePath(ClassGenerator.fileName(type) + ".h"); includePath(fileNames.fileName(type) + ".h");
} }
public void includePath(String fileName) { public void includePath(String fileName) {

View File

@ -0,0 +1,79 @@
/*
* Copyright 2021 konso.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.backend.c.generate;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.teavm.model.ValueType;
public class ShorteningFileNameProvider implements FileNameProvider {
private final FileNameProvider nameProvider;
private final Map<String, String> names = new HashMap<>();
private final Set<String> usedNames = new HashSet<>();
public ShorteningFileNameProvider(FileNameProvider nameProvider) {
this.nameProvider = nameProvider;
}
@Override
public String fileName(String className) {
return unique(shorten(nameProvider.fileName(className)));
}
@Override
public String fileName(ValueType type) {
return unique(shorten(nameProvider.fileName(type)));
}
@Override
public String escapeName(String name) {
return unique(shorten(nameProvider.escapeName(name)));
}
private String unique(String name) {
return names.computeIfAbsent(name, n -> {
if (usedNames.add(n)) {
return n;
}
int suffix = 1;
while (true) {
String candidate = n + "_" + suffix++;
if (usedNames.add(candidate)) {
return candidate;
}
}
});
}
private static String shorten(String name) {
StringBuilder sb = new StringBuilder();
int index = 0;
while (true) {
int next = name.indexOf('/', index);
if (next < 0) {
break;
}
if (next > index) {
sb.append(name.charAt(index));
}
sb.append('/');
index = next + 1;
}
return sb.append(name, index, name.length()).toString();
}
}

View File

@ -0,0 +1,128 @@
/*
* Copyright 2021 konso.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.backend.c.generate;
import org.teavm.model.ValueType;
public class SimpleFileNameProvider implements FileNameProvider {
@Override
public String fileName(String className) {
StringBuilder sb = new StringBuilder("classes/");
escape(className, sb);
return sb.toString();
}
@Override
public String fileName(ValueType type) {
StringBuilder sb = new StringBuilder();
fileNameRec(type, sb);
return sb.toString();
}
private static void fileNameRec(ValueType type, StringBuilder sb) {
if (type instanceof ValueType.Object) {
sb.append("classes/");
escape(((ValueType.Object) type).getClassName(), sb);
} else if (type instanceof ValueType.Array) {
sb.append("arrays/");
fileNameRec(((ValueType.Array) type).getItemType(), sb);
} else if (type instanceof ValueType.Primitive) {
sb.append("primitives/");
switch (((ValueType.Primitive) type).getKind()) {
case BOOLEAN:
sb.append("boolean");
break;
case BYTE:
sb.append("byte");
break;
case SHORT:
sb.append("short");
break;
case CHARACTER:
sb.append("char");
break;
case INTEGER:
sb.append("int");
break;
case LONG:
sb.append("long");
break;
case FLOAT:
sb.append("float");
break;
case DOUBLE:
sb.append("double");
break;
}
} else if (type == ValueType.VOID) {
sb.append("primitives/void");
}
}
@Override
public String escapeName(String name) {
StringBuilder sb = new StringBuilder();
escape(name, sb);
return sb.toString();
}
private static void escape(String className, StringBuilder sb) {
for (int i = 0; i < className.length(); ++i) {
char c = className.charAt(i);
switch (c) {
case '.':
sb.append('/');
break;
case '@':
sb.append("@@");
break;
case '/':
sb.append("@s");
break;
case '\\':
sb.append("@b");
break;
case ':':
sb.append("@c");
break;
case ';':
sb.append("@e");
break;
case '*':
sb.append("@m");
break;
case '"':
sb.append("@q");
break;
case '<':
sb.append("@l");
break;
case '>':
sb.append("@g");
break;
case '|':
sb.append("@p");
break;
case '$':
sb.append("@d");
break;
default:
sb.append(c);
break;
}
}
}
}

View File

@ -23,7 +23,8 @@ public class SimpleIncludeManager extends IncludeManager {
private CodeWriter writer; private CodeWriter writer;
private CodeWriter emptyLine; private CodeWriter emptyLine;
public SimpleIncludeManager(CodeWriter writer) { public SimpleIncludeManager(FileNameProvider fileNames, CodeWriter writer) {
super(fileNames);
this.writer = writer.fragment(); this.writer = writer.fragment();
emptyLine = writer.fragment(); emptyLine = writer.fragment();
} }

View File

@ -34,6 +34,8 @@ import java.util.Properties;
import java.util.Set; import java.util.Set;
import org.teavm.backend.c.CTarget; import org.teavm.backend.c.CTarget;
import org.teavm.backend.c.generate.CNameProvider; import org.teavm.backend.c.generate.CNameProvider;
import org.teavm.backend.c.generate.ShorteningFileNameProvider;
import org.teavm.backend.c.generate.SimpleFileNameProvider;
import org.teavm.backend.javascript.JavaScriptTarget; import org.teavm.backend.javascript.JavaScriptTarget;
import org.teavm.backend.wasm.WasmTarget; import org.teavm.backend.wasm.WasmTarget;
import org.teavm.backend.wasm.render.WasmBinaryVersion; import org.teavm.backend.wasm.render.WasmBinaryVersion;
@ -108,6 +110,7 @@ public class TeaVMTool {
private ReferenceCache referenceCache; private ReferenceCache referenceCache;
private boolean longjmpSupported = true; private boolean longjmpSupported = true;
private boolean heapDump; private boolean heapDump;
private boolean shortFileNames;
public File getTargetDirectory() { public File getTargetDirectory() {
return targetDirectory; return targetDirectory;
@ -261,6 +264,10 @@ public class TeaVMTool {
this.heapDump = heapDump; this.heapDump = heapDump;
} }
public void setShortFileNames(boolean shortFileNames) {
this.shortFileNames = shortFileNames;
}
public void setProgressListener(TeaVMProgressListener progressListener) { public void setProgressListener(TeaVMProgressListener progressListener) {
this.progressListener = progressListener; this.progressListener = progressListener;
} }
@ -342,6 +349,9 @@ public class TeaVMTool {
cTarget.setLongjmpUsed(longjmpSupported); cTarget.setLongjmpUsed(longjmpSupported);
cTarget.setHeapDump(heapDump); cTarget.setHeapDump(heapDump);
cTarget.setObfuscated(obfuscated); cTarget.setObfuscated(obfuscated);
cTarget.setFileNames(shortFileNames
? new ShorteningFileNameProvider(new SimpleFileNameProvider())
: new SimpleFileNameProvider());
return cTarget; return cTarget;
} }

View File

@ -82,5 +82,7 @@ public interface BuildStrategy {
void setHeapDump(boolean heapDump); void setHeapDump(boolean heapDump);
void setShortFileNames(boolean shortFileNames);
BuildResult build() throws BuildException; BuildResult build() throws BuildException;
} }

View File

@ -68,6 +68,7 @@ public class InProcessBuildStrategy implements BuildStrategy {
private TeaVMProgressListener progressListener; private TeaVMProgressListener progressListener;
private Properties properties = new Properties(); private Properties properties = new Properties();
private TeaVMToolLog log = new EmptyTeaVMToolLog(); private TeaVMToolLog log = new EmptyTeaVMToolLog();
private boolean shortFileNames;
public InProcessBuildStrategy(ClassLoaderFactory classLoaderFactory) { public InProcessBuildStrategy(ClassLoaderFactory classLoaderFactory) {
this.classLoaderFactory = classLoaderFactory; this.classLoaderFactory = classLoaderFactory;
@ -220,6 +221,11 @@ public class InProcessBuildStrategy implements BuildStrategy {
this.heapDump = heapDump; this.heapDump = heapDump;
} }
@Override
public void setShortFileNames(boolean shortFileNames) {
this.shortFileNames = shortFileNames;
}
@Override @Override
public BuildResult build() throws BuildException { public BuildResult build() throws BuildException {
TeaVMTool tool = new TeaVMTool(); TeaVMTool tool = new TeaVMTool();
@ -250,6 +256,7 @@ public class InProcessBuildStrategy implements BuildStrategy {
tool.setMaxHeapSize(maxHeapSize); tool.setMaxHeapSize(maxHeapSize);
tool.setLongjmpSupported(longjmpSupported); tool.setLongjmpSupported(longjmpSupported);
tool.setHeapDump(heapDump); tool.setHeapDump(heapDump);
tool.setShortFileNames(shortFileNames);
tool.getProperties().putAll(properties); tool.getProperties().putAll(properties);

View File

@ -195,6 +195,11 @@ public class RemoteBuildStrategy implements BuildStrategy {
request.heapDump = heapDump; request.heapDump = heapDump;
} }
@Override
public void setShortFileNames(boolean shortFileNames) {
request.shortFileNames = shortFileNames;
}
@Override @Override
public BuildResult build() throws BuildException { public BuildResult build() throws BuildException {
RemoteBuildResponse response; RemoteBuildResponse response;

View File

@ -163,6 +163,7 @@ public class BuildDaemon extends UnicastRemoteObject implements RemoteBuildServi
tool.setMaxHeapSize(request.maxHeapSize); tool.setMaxHeapSize(request.maxHeapSize);
tool.setLongjmpSupported(request.longjmpSupported); tool.setLongjmpSupported(request.longjmpSupported);
tool.setHeapDump(request.heapDump); tool.setHeapDump(request.heapDump);
tool.setShortFileNames(request.shortFileNames);
for (String sourceDirectory : request.sourceDirectories) { for (String sourceDirectory : request.sourceDirectories) {
tool.addSourceFileProvider(new DirectorySourceFileProvider(new File(sourceDirectory))); tool.addSourceFileProvider(new DirectorySourceFileProvider(new File(sourceDirectory)));

View File

@ -50,4 +50,5 @@ public class RemoteBuildRequest implements Serializable {
public int maxHeapSize; public int maxHeapSize;
public boolean longjmpSupported; public boolean longjmpSupported;
public boolean heapDump; public boolean heapDump;
public boolean shortFileNames;
} }

View File

@ -158,6 +158,9 @@ public class TeaVMCompileMojo extends AbstractMojo {
@Parameter(property = "teavm.heapDump", defaultValue = "false") @Parameter(property = "teavm.heapDump", defaultValue = "false")
private boolean heapDump; private boolean heapDump;
@Parameter(property = "teavm.shortFileNames", defaultValue = "false")
private boolean shortFileNames;
private void setupBuilder(BuildStrategy builder) throws MojoExecutionException { private void setupBuilder(BuildStrategy builder) throws MojoExecutionException {
builder.setLog(new MavenTeaVMToolLog(getLog())); builder.setLog(new MavenTeaVMToolLog(getLog()));
try { try {
@ -182,6 +185,7 @@ public class TeaVMCompileMojo extends AbstractMojo {
builder.setSourceFilesCopied(sourceFilesCopied); builder.setSourceFilesCopied(sourceFilesCopied);
builder.setMinHeapSize(minHeapSize * 1024 * 1024); builder.setMinHeapSize(minHeapSize * 1024 * 1024);
builder.setMaxHeapSize(maxHeapSize * 1024 * 1024); builder.setMaxHeapSize(maxHeapSize * 1024 * 1024);
builder.setShortFileNames(shortFileNames);
} catch (RuntimeException e) { } catch (RuntimeException e) {
throw new MojoExecutionException("Unexpected error occurred", e); throw new MojoExecutionException("Unexpected error occurred", e);
} }