From f7b257a9a219c44741802251a920fda33c48ec69 Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Thu, 21 Feb 2008 08:34:01 +0000 Subject: [PATCH] Action to create a parser log, bug 213561. --- .../internal/core/model/TranslationUnit.java | 2 +- .../core/parser/ParserMessages.properties | 2 +- .../parser/scanner/ASTPreprocessorNode.java | 30 ++ core/org.eclipse.cdt.ui/plugin.properties | 1 + core/org.eclipse.cdt.ui/plugin.xml | 24 ++ .../ui/actions/ActionMessages.properties | 4 +- .../ui/actions/CreateParserLogAction.java | 327 ++++++++++++++++++ 7 files changed, 387 insertions(+), 3 deletions(-) create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/CreateParserLogAction.java diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java index e9580a9ab65..5530d8060ea 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java @@ -832,7 +832,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit { } private static int[] CTX_LINKAGES= {ILinkage.CPP_LINKAGE_ID, ILinkage.C_LINKAGE_ID}; - private ITranslationUnit getSourceContextTU(IIndex index, int style) { + public ITranslationUnit getSourceContextTU(IIndex index, int style) { if (index != null && (style & AST_CONFIGURE_USING_SOURCE_CONTEXT) != 0) { try { fLanguageOfContext= null; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ParserMessages.properties b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ParserMessages.properties index 5e828321b30..0d8d8cd8c22 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ParserMessages.properties +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ParserMessages.properties @@ -65,7 +65,7 @@ ASTProblemFactory.error.semantic.malformedExpression=Malformed expression LineOffsetReconciler.error.couldNotResetReader=Could not reset Reader -BaseProblemFactory.problemPattern={0} in file: {1}:{2, number, integer}. +BaseProblemFactory.problemPattern={0} in file: {1}:{2, number, integer} ASTProblemFactory.error.semantic.pst.ambiguousLookup=Ambiguity encountered during lookup: {0} ASTProblemFactory.error.semantic.pst.invalidType=Invalid type encountered in: {0} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java index e9c6ac642bd..ab61429754a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java @@ -220,6 +220,7 @@ class ASTInclusionStatement extends ASTPreprocessorNode implements IASTPreproces return fIsSystemInclude; } + @Override IASTNode findSurroundingNode(int sequenceNumber, int length) { final int nameSequencNumber= fName.getOffset(); final int nameEndSequencNumber= nameSequencNumber + fName.getLength(); @@ -258,6 +259,7 @@ class ASTMacroDefinition extends ASTPreprocessorNode implements IASTPreprocessor } + @Override public String getContainingFilename() { if (fName instanceof ASTBuiltinName) { return fName.getContainingFilename(); @@ -281,6 +283,7 @@ class ASTMacroDefinition extends ASTPreprocessorNode implements IASTPreprocessor return (fName == n) ? r_definition : r_unclear; } + @Override IASTNode findSurroundingNode(int sequenceNumber, int length) { final int nameSequencNumber= fName.getOffset(); final int nameEndSequencNumber= nameSequencNumber + fName.getLength(); @@ -312,6 +315,11 @@ class ASTMacroDefinition extends ASTPreprocessorNode implements IASTPreprocessor } return null; } + + @Override + public String toString() { + return getName().toString() + '=' + getExpansion(); + } } class ASTMacroParameter extends ASTPreprocessorNode implements IASTFunctionStyleMacroParameter { @@ -357,6 +365,25 @@ class ASTFunctionStyleMacroDefinition extends ASTMacroDefinition implements IAST } public void addParameter(IASTFunctionStyleMacroParameter parm) {assert false;} + + @Override + public String toString() { + StringBuilder result= new StringBuilder(); + result.append(getName().toCharArray()); + result.append('('); + boolean needComma= false; + for (IASTFunctionStyleMacroParameter param : getParameters()) { + if (needComma) { + result.append(','); + } + result.append(param.getParameter()); + needComma= true; + } + result.append(')'); + result.append('='); + result.append(getExpansion()); + return result.toString(); + } } @@ -371,6 +398,7 @@ class ASTUndef extends ASTPreprocessorNode implements IASTPreprocessorUndefState return fName; } + @Override IASTNode findSurroundingNode(int sequenceNumber, int length) { final int nameSequencNumber= fName.getOffset(); final int nameEndSequencNumber= nameSequencNumber + fName.getLength(); @@ -457,6 +485,7 @@ class ASTFileLocation implements IASTFileLocation { return fLocationCtx.getSource(fOffset, fLength); } + @Override public String toString() { return getFileName() + "[" + fOffset + "," + (fOffset+fLength) + ")"; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ } @@ -511,6 +540,7 @@ class ASTMacroExpansionLocation implements IASTMacroExpansion { return fOffset; } + @Override public String toString() { return fContext.getMacroDefinition().getName().toString() + "[" + fOffset + "," + (fOffset+fLength) + ")"; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ } diff --git a/core/org.eclipse.cdt.ui/plugin.properties b/core/org.eclipse.cdt.ui/plugin.properties index e68a00c93d9..5d088da9112 100644 --- a/core/org.eclipse.cdt.ui/plugin.properties +++ b/core/org.eclipse.cdt.ui/plugin.properties @@ -380,6 +380,7 @@ RebuildIndex.name=&Rebuild SyncIndex.name=&Update with Modified Files FreshenIndex.name=&Freshen All Files SearchUnresolvedIncludes.name=Search for Unresolved &Includes +CreateParserLog.name=Create Parser &Log File indexerPage.name = Indexer Page proposalFilter.name = Code Completion Proposal Filter diff --git a/core/org.eclipse.cdt.ui/plugin.xml b/core/org.eclipse.cdt.ui/plugin.xml index 970095ff92c..d9e82604f89 100644 --- a/core/org.eclipse.cdt.ui/plugin.xml +++ b/core/org.eclipse.cdt.ui/plugin.xml @@ -824,6 +824,28 @@ + + + + + + + + + + + + + + @@ -884,6 +907,7 @@ + fProblems= new ArrayList(); + List fProblemBindings= new ArrayList(); + List fExceptions= new ArrayList(); + + MyVisitor() { + shouldVisitProblems= true; + shouldVisitNames= true; + } + + @Override + public int visit(IASTProblem problem) { + fProblems.add(problem); + return PROCESS_SKIP; + } + + @Override + public int visit(IASTName name) { + if (name instanceof ICPPASTQualifiedName) { + return PROCESS_CONTINUE; + } + try { + IBinding binding= name.resolveBinding(); + if (binding instanceof IProblemBinding) { + fProblemBindings.add((IProblemBinding) binding); + } + } catch (RuntimeException e) { + fExceptions.add(e); + } + return PROCESS_CONTINUE; + } + } + + private ISelection fSelection; + private IWorkbenchPartSite fSite; + + public void setActivePart(IAction action, IWorkbenchPart targetPart) { + fSite= targetPart.getSite(); + } + + public void selectionChanged(IAction action, ISelection selection) { + fSelection = selection; + } + + public void run(IAction action) { + if (!(fSelection instanceof IStructuredSelection)) + return; + + final String title= action.getText().replace("&", ""); //$NON-NLS-1$ //$NON-NLS-2$ + IStructuredSelection cElements= SelectionConverter.convertSelectionToCElements(fSelection); + Iterator i= cElements.iterator(); + ArrayList tuSelection= new ArrayList(); + while (i.hasNext()) { + Object o= i.next(); + if (o instanceof ITranslationUnit) { + tuSelection.add((ITranslationUnit) o); + } + } + ITranslationUnit[] tuArray= tuSelection.toArray(new ITranslationUnit[tuSelection.size()]); + if (tuArray.length == 0) { + return; + } + FileDialog dlg= new FileDialog(fSite.getShell(), SWT.SAVE); + dlg.setText(title); + dlg.setFilterExtensions(new String[]{"*.log"}); //$NON-NLS-1$ + String path= null; + while(path == null) { + path= dlg.open(); + if (path == null) + return; + + File file= new File(path); + if (file.exists()) { + if (!file.canWrite()) { + final String msg= NLS.bind(ActionMessages.getString("CreateParserLogAction.readOnlyFile"), path); //$NON-NLS-1$ + MessageDialog.openError(fSite.getShell(), title, msg); + path= null; + } + else { + final String msg = NLS.bind(ActionMessages.getString("CreateParserLogAction.existingFile"), path); //$NON-NLS-1$ + if (!MessageDialog.openQuestion(fSite.getShell(), title, msg)) { + path= null; + } + } + } + } + + try { + PrintStream out= new PrintStream(path); + try { + boolean needsep= false; + for (ITranslationUnit tu : tuArray) { + if (needsep) { + out.println(); out.println(); + } + createLog(out, tu, new NullProgressMonitor()); + needsep= true; + } + } + finally { + out.close(); + } + } catch (IOException e) { + MessageDialog.openError(fSite.getShell(), action.getText(), e.getMessage()); + } + } + + private void createLog(final PrintStream out, final ITranslationUnit tu, IProgressMonitor pm) { + ASTProvider.getASTProvider().runOnAST(tu, ASTProvider.WAIT_YES, pm, new ASTCache.ASTRunnable() { + public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) throws CoreException { + return createLog(out, tu, lang, ast); + } + }); + } + + protected IStatus createLog(PrintStream out, ITranslationUnit tu, ILanguage lang, IASTTranslationUnit ast) { + IStatus status = Status.OK_STATUS; + final ICProject cproject = tu.getCProject(); + final String projectName= cproject == null ? null : cproject.getElementName(); + + ITranslationUnit ctx= tu; + if (tu instanceof TranslationUnit) { + TranslationUnit itu= (TranslationUnit) tu; + ctx= itu.getSourceContextTU(ast.getIndex(), ITranslationUnit.AST_CONFIGURE_USING_SOURCE_CONTEXT); + } + final ExtendedScannerInfo scfg= new ExtendedScannerInfo(ctx.getScannerInfo(true)); + final String indent= " "; //$NON-NLS-1$ + final MyVisitor visitor= new MyVisitor(); + ast.accept(visitor); + + out.println("Project: " + projectName); //$NON-NLS-1$ + out.println("Index Version: " + PDOM.CURRENT_VERSION); //$NON-NLS-1$ + out.println("File: " + tu.getLocationURI()); //$NON-NLS-1$ + out.println("Context: " + ctx.getLocationURI()); //$NON-NLS-1$ + out.println("Language: " + lang.getName()); //$NON-NLS-1$ + out.println(); + out.println("Include Search Path (option -I):"); //$NON-NLS-1$ + output(out, indent, scfg.getIncludePaths()); + out.println(); + out.println("Local Include Search Path (option -iquote):"); //$NON-NLS-1$ + output(out, indent, scfg.getLocalIncludePath()); + out.println(); + out.println("Preincluded files (option -include):"); //$NON-NLS-1$ + output(out, indent, scfg.getIncludeFiles()); + out.println(); + out.println("Preincluded macro files (option -imacros):"); //$NON-NLS-1$ + output(out, indent, scfg.getMacroFiles()); + out.println(); + out.println("Macro definitions (option -D):"); //$NON-NLS-1$ + HashSet reported= new HashSet(); + output(out, indent, scfg.getDefinedSymbols(), reported); + out.println(); + out.println("Macro definitions (from configuration + headers in index):"); //$NON-NLS-1$ + output(out, indent, ast.getBuiltinMacroDefinitions(), reported); + out.println(); + out.println("Macro definitions (from files actually parsed):"); //$NON-NLS-1$ + output(out, indent, ast.getMacroDefinitions(), reported); + + out.println(); + out.println("Unresolved includes (from headers in index):"); //$NON-NLS-1$ + try { + outputUnresolvedIncludes(cproject, ast.getIndex(), out, indent, ast.getIncludeDirectives(), ast.getLinkage().getLinkageID()); + } catch (CoreException e) { + status= e.getStatus(); + } + + out.println(); + out.println("Scanner problems:"); //$NON-NLS-1$ + output(out, indent, ast.getPreprocessorProblems()); + + out.println(); + out.println("Parser problems:"); //$NON-NLS-1$ + output(out, indent, visitor.fProblems.toArray(new IASTProblem[visitor.fProblems.size()])); + + out.println(); + out.println("Unresolved names:"); //$NON-NLS-1$ + output(out, indent, visitor.fProblemBindings); + + out.println(); + out.println("Exceptions in name resolution:"); //$NON-NLS-1$ + output(out, visitor.fExceptions); + + return status; + } + + private void outputUnresolvedIncludes(ICProject prj, IIndex index, PrintStream out, String indent, + IASTPreprocessorIncludeStatement[] includeDirectives, int linkageID) throws CoreException { + ASTFilePathResolver resolver= new ProjectIndexerInputAdapter(prj); + for (IASTPreprocessorIncludeStatement include : includeDirectives) { + if (include.isActive() && include.isResolved()) { + outputUnresolvedIncludes(index, out, indent, resolver.resolveASTPath(include.getPath()), linkageID); + } + } + } + + private void outputUnresolvedIncludes(IIndex index, PrintStream out, String indent, + IIndexFileLocation ifl, int linkageID) throws CoreException { + IIndexFile ifile= index.getFile(linkageID, ifl); + if (ifile == null) { + out.println(indent + ifl.getURI() + " is not indexed"); //$NON-NLS-1$ + } + else { + IIndexInclude[] includes = ifile.getIncludes(); + for (IIndexInclude inc : includes) { + if (inc.isActive()) { + if (inc.isResolved()) { + outputUnresolvedIncludes(index, out, indent, inc.getIncludesLocation(), linkageID); + } + else { + out.println(indent + "Unresolved inclusion: " + inc.getName() + " in file " + //$NON-NLS-1$//$NON-NLS-2$ + inc.getIncludedByLocation().getURI()); + } + } + } + } + } + + private void output(PrintStream out, String indent, String[] list) { + for (String line : list) { + out.println(indent + line); + } + } + + private void output(PrintStream out, String indent, Map definedSymbols, HashSet reported) { + for (Entry entry : definedSymbols.entrySet()) { + final String macro = entry.getKey() + '=' + entry.getValue(); + if (reported.add(macro)) { + out.println(indent + macro); + } + } + } + + private void output(PrintStream out, String indent, IASTPreprocessorMacroDefinition[] defs, HashSet reported) { + for (IASTPreprocessorMacroDefinition def : defs) { + String macro= def.toString(); + if (reported.add(macro)) { + out.println(indent + macro); + } + } + } + + private void output(PrintStream out, String indent, IASTProblem[] preprocessorProblems) { + for (IASTProblem problem : preprocessorProblems) { + out.println(indent + problem.getMessage()); + } + } + + private void output(PrintStream out, String indent, List list) { + for (IProblemBinding problem : list) { + String file= problem.getFileName(); + int line = problem.getLineNumber(); + out.println(indent + problem.getMessage() + " in file " + file + ':' + line); //$NON-NLS-1$ + } + } + + private void output(PrintStream out, List list) { + for (Exception problem : list) { + problem.printStackTrace(out); + } + } +}