/* * Copyright 2009-2016 the original author or authors. * * 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.codehaus.groovy.eclipse.core.compiler; import java.util.Iterator; import java.util.Map; import groovyjarjarasm.asm.Opcodes; import org.codehaus.groovy.ast.ClassNode; import org.codehaus.groovy.ast.MethodNode; import org.codehaus.groovy.ast.ModuleNode; import org.codehaus.groovy.eclipse.core.GroovyCore; import org.codehaus.groovy.eclipse.core.model.GroovyProjectFacade; import org.codehaus.jdt.groovy.internal.compiler.ast.GroovyCompilationUnitDeclaration; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.WorkingCopyOwner; import org.eclipse.jdt.core.dom.CompilationUnitResolver; import org.eclipse.jdt.groovy.core.util.ContentTypeUtils; import org.eclipse.jdt.internal.compiler.CompilationResult; import org.eclipse.jdt.internal.compiler.Compiler; import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies; import org.eclipse.jdt.internal.compiler.ICompilerRequestor; import org.eclipse.jdt.internal.compiler.env.INameEnvironment; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory; import org.eclipse.jdt.internal.core.JavaProject; import org.eclipse.jdt.internal.core.SearchableEnvironment; /** * @author Andrew Eisenberg * @created Aug 6, 2009 * * * This class is used to compile a snippet of groovy source code into a * module node. * The client is responsible for calling {@link #cleanup()} when all * {@link ClassNode}s * created by this compiler are no longer needed */ public class GroovySnippetCompiler { /** * @author Andrew Eisenberg * @created Aug 6, 2009 * Provide an empty requestor, no compilation results required */ private static class Requestor implements ICompilerRequestor { public void acceptResult(CompilationResult result) { } } private INameEnvironment nameEnvironment; public GroovySnippetCompiler(GroovyProjectFacade project) { try { nameEnvironment = new SearchableEnvironment((JavaProject) project.getProject(), (WorkingCopyOwner) null); } catch (JavaModelException e) { GroovyCore .logException("Problem initializing snippet compiler for project " + project.getProject().getElementName(), e); } } /** * Compiles source code into a ModuleNode. Source code * must be a complete file including package declaration * and import statements. * * @param source the groovy source code to compile * @param sourcePath the path including file name to compile. Can be null */ public ModuleNode compile(String source, String sourcePath) { GroovyCompilationUnitDeclaration decl = internalCompile(source, sourcePath); ModuleNode node = decl.getModuleNode(); // Remove any remaining synthetic methods for (ClassNode classNode : (Iterable<ClassNode>) node.getClasses()) { for (Iterator<MethodNode> methodIter = classNode.getMethods().iterator(); methodIter.hasNext();) { MethodNode method = methodIter.next(); if ((method.getModifiers() & Opcodes.ACC_SYNTHETIC) != 0) { methodIter.remove(); } } } return node; } public CompilationResult compileForErrors(String source, String sourcePath) { GroovyCompilationUnitDeclaration unit = internalCompile(source, sourcePath); return unit.compilationResult(); } private GroovyCompilationUnitDeclaration internalCompile(String source, String sourcePath) { if (sourcePath == null) { sourcePath = "Nothing.groovy"; } else if (! ContentTypeUtils.isGroovyLikeFileName(sourcePath)) { sourcePath = sourcePath.concat(".groovy"); } Map<String, String> options = JavaCore.getOptions(); options.put(CompilerOptions.OPTIONG_BuildGroovyFiles, CompilerOptions.ENABLED); Compiler compiler = new CompilationUnitResolver(nameEnvironment, DefaultErrorHandlingPolicies.proceedWithAllProblems(), new CompilerOptions(options), new Requestor(), new DefaultProblemFactory(), null, true); GroovyCompilationUnitDeclaration decl = (GroovyCompilationUnitDeclaration) compiler.resolve(new MockCompilationUnit(source.toCharArray(), sourcePath.toCharArray()), true, false, false); return decl; } public void cleanup() { nameEnvironment.cleanup(); } /** * Compile source code into a module node when * there is no file name */ public ModuleNode compile(String source) { return compile(source, null); } }