package gool.parser.cpp;
import gool.ParseGOOL;
import gool.Settings;
import gool.ast.core.ClassDef;
import gool.generator.common.Platform;
import gool.recognizer.cpp.CppRecognizer;
import gool.recognizer.cpp.CppRecognizerImport;
import gool.recognizer.cpp.ast.ASTCppNode;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.model.ILanguage;
import org.eclipse.cdt.core.parser.DefaultLogService;
import org.eclipse.cdt.core.parser.FileContent;
import org.eclipse.cdt.core.parser.IParserLogService;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.core.parser.IncludeFileContentProvider;
import org.eclipse.cdt.core.parser.ScannerInfo;
/**
* This class parses concrete Cpp into abstract GOOL. For this purpose it
* relies on Eclipse's CDT parser.
*/
public class CppParser extends ParseGOOL {
/**
* The real parser GOOL, which transforms a C++ AST into a GOOL AST.
* @param defaultPlatform
* : The default platform.
* @param translationUnits
* : The collection of transition units which can be transformed into GOOL AST.
* @param dependencies
* : List of dependencies files.
* @param visitor
* : The visitor, which create the GOOL AST (ie. the Recognizer).
* @return
* The GOOL AST associated to the transition units.
* @throws Exception
*/
public static Collection<ClassDef> parseGool(Platform defaultPlatform,
Collection<IASTTranslationUnit> translationUnits,
List<File> dependencies, CppRecognizer visitor) throws Exception {
if (visitor == null) {
throw new IllegalArgumentException("The gool visitor is null.");
}
visitor.setDefaultPlatform(defaultPlatform);
for(IASTTranslationUnit translationUnit : translationUnits){
ASTCppNode.transforme(translationUnit).accept(visitor,null);
}
for (ClassDef classDef : visitor.getGoolClasses()) {
classDef.getPlatform().registerCustomDependency(
classDef.getName(), new ClassDef(classDef.getName() + ".h"));
}
return visitor.getGoolClasses();
}
@Override
public Collection<ClassDef> parseGool(Platform defaultPlatform, String input)
throws Exception {
Collection<IASTTranslationUnit> translationUnits = new ArrayList<IASTTranslationUnit>();
IASTTranslationUnit tu = creatIASTTranslationUnit(input) ;
// First step : indirect input usage case.
CppRecognizerImport visitImport = new CppRecognizerImport() ;
ASTCppNode.transforme(tu).accept(visitImport,null);
translationUnits.add(tu);
for(String dep : visitImport.getFilesAdd())
translationUnits.add(creatIASTTranslationUnit(
FileContent.createForExternalFileLocation(new File(dep).getPath())
));
// transformed into a GOOL AST : second step. Parse files in folder cpp_in_tmp.
return parseGool(defaultPlatform, translationUnits, null, new CppRecognizer());
}
@Override
public Collection<ClassDef> parseGool(Platform defaultPlatform,
Collection<? extends File> inputFiles) throws Exception {
Collection<IASTTranslationUnit> translationUnits = new ArrayList<IASTTranslationUnit>();
// First step : indirect input usage case.
for(File input : inputFiles)
{
IASTTranslationUnit tu = creatIASTTranslationUnit(
FileContent.createForExternalFileLocation(input.getPath())
);
CppRecognizerImport visitImport = new CppRecognizerImport() ;
ASTCppNode.transforme(tu).accept(visitImport,null);
translationUnits.add(tu);
for(String dep : visitImport.getFilesAdd())
translationUnits.add(creatIASTTranslationUnit(
FileContent.createForExternalFileLocation(new File(dep).getPath())
));
}
// transformed into a GOOL AST : second step. Parse files in folder cpp_in_tmp.
return parseGool(defaultPlatform, translationUnits, null, new CppRecognizer());
}
/**
* To parse C++ as a file.
* @param input
* : The code C++ in input as a file.
* @return
* A transition unit about the input file.
* @throws Exception
*/
public static IASTTranslationUnit creatIASTTranslationUnit(FileContent input) throws Exception {
Map<String, String> macroDefinitions = new HashMap<String, String>();
String[] includeSearchPaths = Settings.get("cpp_in_libraries").split(" ");
IScannerInfo si = new ScannerInfo(macroDefinitions, includeSearchPaths);
IncludeFileContentProvider ifcp = IncludeFileContentProvider.getEmptyFilesProvider();
IIndex idx = null;
int options = ILanguage.OPTION_IS_SOURCE_UNIT;
IParserLogService log = new DefaultLogService();
return GPPLanguage.getDefault().getASTTranslationUnit(input, si, ifcp, idx, options, log);
}
/**
* To parse C++ as string.
* @param input
* : The code C++ in input as string.
* @return
* A transition unit about the input string.
* @throws Exception
*/
public static IASTTranslationUnit creatIASTTranslationUnit(String input) throws Exception {
FileContent fc = FileContent.create("Test.cpp", input.toCharArray());
return creatIASTTranslationUnit(fc);
}
}