diff options
author | peichhorn <peichhor@web.de> | 2011-06-01 02:44:53 +0200 |
---|---|---|
committer | peichhorn <peichhor@web.de> | 2011-06-01 02:44:53 +0200 |
commit | 850c3eaf07cd4beb2276b5e10296132b6ed3d7a6 (patch) | |
tree | 0c655e95d0979a2e2a500eafc4bb8011f892f9ab /test/core/src/lombok | |
parent | aa96fcbc7724ccd0306b6df0b1aaa9f86aa1d507 (diff) | |
download | lombok-850c3eaf07cd4beb2276b5e10296132b6ed3d7a6.tar.gz lombok-850c3eaf07cd4beb2276b5e10296132b6ed3d7a6.tar.bz2 lombok-850c3eaf07cd4beb2276b5e10296132b6ed3d7a6.zip |
Added a test infrastructure that simulates eclipse with diet-parse, type-binding and so forth. Similar to eclipse, the test needs to be executed with lombok as vm-agent. @Delegate runs with this setup, sadly val does not, at least for now.
And as expected the tests shows that @Synchronized and @SneakyThrows are currently broken for eclipse but not for ecj.
Diffstat (limited to 'test/core/src/lombok')
-rw-r--r-- | test/core/src/lombok/DirectoryRunner.java | 4 | ||||
-rw-r--r-- | test/core/src/lombok/RunTestsViaEclipse.java | 304 |
2 files changed, 307 insertions, 1 deletions
diff --git a/test/core/src/lombok/DirectoryRunner.java b/test/core/src/lombok/DirectoryRunner.java index f84198f8..39e2b792 100644 --- a/test/core/src/lombok/DirectoryRunner.java +++ b/test/core/src/lombok/DirectoryRunner.java @@ -37,7 +37,7 @@ import org.junit.runner.notification.RunNotifier; public class DirectoryRunner extends Runner { public enum Compiler { - DELOMBOK, JAVAC, ECJ; + DELOMBOK, JAVAC, ECJ, ECLIPSE; } public interface TestParams { @@ -119,6 +119,8 @@ public class DirectoryRunner extends Runner { switch (params.getCompiler()) { case DELOMBOK: return new RunTestsViaDelombok().compareFile(params, file); + case ECLIPSE: + return new RunTestsViaEclipse().compareFile(params, file); case ECJ: return new RunTestsViaEcj().compareFile(params, file); default: diff --git a/test/core/src/lombok/RunTestsViaEclipse.java b/test/core/src/lombok/RunTestsViaEclipse.java new file mode 100644 index 00000000..03f205ba --- /dev/null +++ b/test/core/src/lombok/RunTestsViaEclipse.java @@ -0,0 +1,304 @@ +/* + * Copyright © 2011 Reinier Zwitserloot and Roel Spilker. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package lombok; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringWriter; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +import org.eclipse.jdt.core.compiler.CategorizedProblem; +import org.eclipse.jdt.internal.compiler.Compiler; +import org.eclipse.jdt.internal.compiler.CompilationResult; +import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies; +import org.eclipse.jdt.internal.compiler.ICompilerRequestor; +import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy; +import org.eclipse.jdt.internal.compiler.IProblemFactory; +import org.eclipse.jdt.internal.compiler.ISourceElementRequestor; +import org.eclipse.jdt.internal.compiler.SourceElementParser; +import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; +import org.eclipse.jdt.internal.compiler.ast.Expression; +import org.eclipse.jdt.internal.compiler.ast.ImportReference; +import org.eclipse.jdt.internal.compiler.batch.CompilationUnit; +import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; +import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader; +import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException; +import org.eclipse.jdt.internal.compiler.env.ICompilationUnit; +import org.eclipse.jdt.internal.compiler.env.INameEnvironment; +import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer; +import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; +import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory; + +/** + * Simulates more or less what happens in eclipse + */ +public class RunTestsViaEclipse extends AbstractRunTests { + protected static CompilerOptions ecjCompilerOptions() { + CompilerOptions options = new CompilerOptions(); + options.complianceLevel = ClassFileConstants.JDK1_6; + options.sourceLevel = ClassFileConstants.JDK1_6; + options.targetJDK = ClassFileConstants.JDK1_6; + options.parseLiteralExpressionsAsConstants = true; + return options; + } + + @Override public void transformCode(final StringBuilder messages, StringWriter result, File file) throws Throwable { + String source = readFile(file); + CompilationUnit sourceUnit = new CompilationUnit(source.toCharArray(), file.getName(), "UTF-8"); + IErrorHandlingPolicy policy = DefaultErrorHandlingPolicies.proceedWithAllProblems(); + IProblemFactory problemFactory = new DefaultProblemFactory(Locale.ENGLISH); + INameEnvironment nameEnvironment = new LombokTestNameEnvironment(); + ICompilerRequestor compilerRequestor = new LombokTestCompilerRequestor(); + CompilerOptions options = ecjCompilerOptions(); + + + ISourceElementRequestor sourceElementRequestor = new LombokTestSourceElementRequestor(); + SourceElementParser parser = new SourceElementParser(sourceElementRequestor, problemFactory, options, true, true); + final CompilationUnitDeclaration cud = parser.parseCompilationUnit(sourceUnit, true, null); + + final LombokTestCompiler jdtCompiler = new LombokTestCompiler(nameEnvironment, policy, options, compilerRequestor, problemFactory); + jdtCompiler.lookupEnvironment.buildTypeBindings(cud, null); + jdtCompiler.lookupEnvironment.completeTypeBindings(cud, true); + + CategorizedProblem[] problems = cud.compilationResult.getAllProblems(); + + if (problems != null) for (CategorizedProblem p : problems) { + messages.append(String.format("%d %s %s\n", p.getSourceLineNumber(), p.isError() ? "error" : p.isWarning() ? "warning" : "unknown", p.getMessage())); + } + + result.append(cud.toString()); + } + + private static class LombokTestCompiler extends Compiler { + public LombokTestCompiler(INameEnvironment nameEnvironment, IErrorHandlingPolicy policy, CompilerOptions ecjCompilerOptions, ICompilerRequestor requestor, IProblemFactory problemFactory) { + super(nameEnvironment, policy, ecjCompilerOptions, requestor, problemFactory); + } + + @Override protected void handleInternalException(Throwable e, CompilationUnitDeclaration ud, CompilationResult result) { + throw new RuntimeException(e); + } + + @Override public void beginToCompile(ICompilationUnit[] sourceUnits) { + super.beginToCompile(sourceUnits); + } + }; + + private static class LombokTestCompilerRequestor implements ICompilerRequestor { + public void acceptResult(CompilationResult result) { + } + } + + private static class LombokTestSourceElementRequestor implements ISourceElementRequestor { + + @Override public void acceptAnnotationTypeReference(char[][] annotation, int sourceStart, int sourceEnd) { + // do nothing + } + + @Override public void acceptAnnotationTypeReference(char[] annotation, int sourcePosition) { + // do nothing + } + + @Override public void acceptConstructorReference(char[] typeName, int argCount, int sourcePosition) { + // do nothing + } + + @Override public void acceptFieldReference(char[] fieldName, int sourcePosition) { + // do nothing + } + + @Override public void acceptImport(int declarationStart, int declarationEnd, char[][] tokens, boolean onDemand, int modifiers) { + // do nothing + } + + @Override public void acceptLineSeparatorPositions(int[] positions) { + // do nothing + } + + @Override public void acceptMethodReference(char[] methodName, int argCount, int sourcePosition) { + // do nothing + } + + @Override public void acceptPackage(ImportReference importReference) { + // do nothing + } + + @Override public void acceptProblem(CategorizedProblem problem) { + // do nothing + } + + @Override public void acceptTypeReference(char[][] typeName, int sourceStart, int sourceEnd) { + // do nothing + } + + @Override public void acceptTypeReference(char[] typeName, int sourcePosition) { + // do nothing + } + + @Override public void acceptUnknownReference(char[][] name, int sourceStart, int sourceEnd) { + // do nothing + } + + @Override public void acceptUnknownReference(char[] name, int sourcePosition) { + // do nothing + } + + @Override public void enterCompilationUnit() { + // do nothing + } + + @Override public void enterConstructor(MethodInfo methodInfo) { + // do nothing + } + + @Override public void enterField(FieldInfo fieldInfo) { + // do nothing + } + + @Override public void enterInitializer(int declarationStart, int modifiers) { + // do nothing + } + + @Override public void enterMethod(MethodInfo methodInfo) { + // do nothing + } + + @Override public void enterType(TypeInfo typeInfo) { + // do nothing + } + + @Override public void exitCompilationUnit(int declarationEnd) { + // do nothing + } + + @Override public void exitConstructor(int declarationEnd) { + // do nothing + } + + @Override public void exitField(int initializationStart, int declarationEnd, int declarationSourceEnd) { + // do nothing + } + + @Override public void exitInitializer(int declarationEnd) { + // do nothing + } + + @Override public void exitMethod(int declarationEnd, Expression defaultValue) { + // do nothing + } + + @Override public void exitType(int declarationEnd) { + // do nothing + } + } + + private static class LombokTestNameEnvironment implements INameEnvironment { + Map<String, Boolean> packagesCache = new HashMap<String, Boolean>(); + + public NameEnvironmentAnswer findType(final char[][] compoundTypeName) { + final StringBuffer result = new StringBuffer(); + for (int i = 0; i < compoundTypeName.length; i++) { + if (i != 0) { + result.append('.'); + } + result.append(compoundTypeName[i]); + } + return findType(result.toString()); + } + + public NameEnvironmentAnswer findType(final char[] typeName, final char[][] packageName) { + final StringBuffer result = new StringBuffer(); + for (int i = 0; i < packageName.length; i++) { + result.append(packageName[i]); + result.append('.'); + } + result.append(typeName); + return findType(result.toString()); + } + + protected byte[] getClassDefinition(String name) { + name = name.replace(".", "/") + ".class"; + InputStream is = this.getClass().getClassLoader().getResourceAsStream(name); + if (is == null) { + return null; + } + try { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + byte[] buffer = new byte[8192]; + int count; + while ((count = is.read(buffer, 0, buffer.length)) > 0) { + os.write(buffer, 0, count); + } + return os.toByteArray(); + } catch (Exception e) { + throw new RuntimeException(e); + } finally { + try { + is.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + + private NameEnvironmentAnswer findType(final String name) { + try { + byte[] bytes = getClassDefinition(name); + if (bytes != null) { + ClassFileReader classFileReader; + classFileReader = new ClassFileReader(bytes, name.toCharArray(), true); + return new NameEnvironmentAnswer(classFileReader, null); + } + return null; + } catch (ClassFormatException e) { + throw new RuntimeException(e); + } + } + + public boolean isPackage(char[][] parentPackageName, char[] packageName) { + final StringBuilder sb = new StringBuilder(); + if (parentPackageName != null) { + for (char[] p : parentPackageName) { + sb.append(p).append("/"); + } + } + sb.append(packageName); + String name = sb.toString(); + if (packagesCache.containsKey(name)) { + return packagesCache.get(name).booleanValue(); + } + byte[] bytes = getClassDefinition(name); + if (bytes != null) { + packagesCache.put(name, false); + return false; + } + packagesCache.put(name, true); + return true; + } + + public void cleanup() { + } + } +} |