/*
* 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.Hashtable;
import java.util.Iterator;
import java.util.Map;
import groovyjarjarasm.asm.Opcodes;
import org.codehaus.groovy.antlr.AntlrParserPlugin;
import org.codehaus.groovy.antlr.GroovySourceAST;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.MethodNode;
import org.codehaus.groovy.ast.ModuleNode;
import org.codehaus.groovy.control.ParserPlugin;
import org.codehaus.groovy.control.SourceUnit;
import org.codehaus.jdt.groovy.internal.compiler.ast.GroovyCompilationUnitDeclaration;
import org.codehaus.jdt.groovy.internal.compiler.ast.GroovyParser;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.compiler.CategorizedProblem;
import org.eclipse.jdt.groovy.core.util.ReflectionUtils;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
/**
* @author Andrew Eisenberg
* @created Aug 11, 2009
*
* This class is used to parse a snippet of groovy source code into a module node
* The module node is not resolved
*/
public class GroovySnippetParser {
private static class MockCompilationUnit implements ICompilationUnit {
private char[] contents;
private char[] fileName;
MockCompilationUnit(char[] contents, char[] fileName) {
this.contents = contents;
this.fileName = fileName;
}
public char[] getContents() {
return contents;
}
public char[] getMainTypeName() {
return new char[0];
}
public char[][] getPackageName() {
return new char[0][];
}
public char[] getFileName() {
return fileName;
}
public boolean ignoreOptionalProblems() {
return false;
}
}
private CategorizedProblem[] problems;
/**
* 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
*/
public ModuleNode parse(String source) {
Map<String, String> table = JavaCore.getOptions();
table.put(CompilerOptions.OPTIONG_BuildGroovyFiles, CompilerOptions.ENABLED);
CompilerOptions options = new CompilerOptions(table);
ProblemReporter reporter = new ProblemReporter(DefaultErrorHandlingPolicies.proceedWithAllProblems(), options,
new DefaultProblemFactory());
GroovyParser parser = new GroovyParser(options, reporter, false, true);
ICompilationUnit unit = new MockCompilationUnit(source.toCharArray(), "Hello.groovy".toCharArray());
CompilationResult compilationResult = new CompilationResult(unit, 0, 0, options.maxProblemsPerUnit);
GroovyCompilationUnitDeclaration decl =
(GroovyCompilationUnitDeclaration)
parser.dietParse(unit, compilationResult);
ModuleNode node = decl.getModuleNode();
if (node == null) {
return null;
}
// 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();
}
}
}
problems = compilationResult.getErrors();
return node;
}
public CategorizedProblem[] getProblems() {
return problems;
}
public GroovySourceAST parseForCST(String source) {
Hashtable<String, String> table = JavaCore.getOptions();
table.put(CompilerOptions.OPTIONG_BuildGroovyFiles, CompilerOptions.ENABLED);
CompilerOptions options = new CompilerOptions(table);
ProblemReporter reporter = new ProblemReporter(DefaultErrorHandlingPolicies.proceedWithAllProblems(), options,
new DefaultProblemFactory());
GroovyParser parser = new GroovyParser(null, reporter, false, true);
ICompilationUnit unit = new MockCompilationUnit(source.toCharArray(), "Hello.groovy".toCharArray());
CompilationResult compilationResult = new CompilationResult(unit, 0, 0, options.maxProblemsPerUnit);
GroovyCompilationUnitDeclaration decl =
(GroovyCompilationUnitDeclaration)
parser.dietParse(unit, compilationResult);
SourceUnit sourceUnit = decl.getSourceUnit();
ParserPlugin parserPlugin = (ParserPlugin) ReflectionUtils.getPrivateField(SourceUnit.class, "parserPlugin", sourceUnit);
if (parserPlugin instanceof AntlrParserPlugin) {
return (GroovySourceAST) ReflectionUtils.getPrivateField(AntlrParserPlugin.class, "ast", parserPlugin);
} else {
return null;
}
}
}