/******************************************************************************* * Copyright © 2005, 2013 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * *******************************************************************************/ package org.eclipse.edt.ide.core.internal.lookup; import java.io.BufferedReader; import java.io.Reader; import java.io.StringReader; import java.util.Iterator; import java.util.List; import org.eclipse.core.resources.IFile; import org.eclipse.edt.compiler.core.ast.ErrorCorrectingParser; import org.eclipse.edt.compiler.core.ast.File; import org.eclipse.edt.compiler.core.ast.Lexer; import org.eclipse.edt.compiler.core.ast.Node; import org.eclipse.edt.compiler.core.ast.Part; import org.eclipse.edt.compiler.internal.core.builder.BuildException; import org.eclipse.edt.compiler.internal.core.utils.SoftLRUCache; import org.eclipse.edt.ide.core.internal.utils.Util; import org.eclipse.edt.mof.utils.NameUtile; public abstract class AbstractASTManager { private SoftLRUCache fileLRUCache = new SoftLRUCache(); /** * Parse this file into an AST Tree if it does not already exist in the cache. * * The file is read from the disk. */ public File getFileAST(IFile file) { File cachedFile = (File)fileLRUCache.get(file); if(cachedFile == null){ try{ String fileContents = Util.getFileContents(file); cachedFile = getFileAST(file, fileContents); } catch (Exception e) { throw new BuildException(e); } fileLRUCache.put(file, cachedFile); } return cachedFile; } /** * Parse this fileContents into an AST Tree. * * The contents of the file are passed in and will not be read from the disk. * * This method checks the cache for the key first. If the key is registered, then no parsing is done, the cached * version is returned. */ public File getFileAST(Object key, String fileContents){ File result = (File)fileLRUCache.get(key); if(result == null){ result = getFileAST(new BufferedReader(new StringReader(fileContents))); fileLRUCache.put(key, result); } return result; } /** * Parse this file into an AST Tree. * * The contents of the file are passed in and will not be read from the disk. * * This method assumes that the file contents being passed in are the "latest and greatest", and will replace any previously cached versions of the file. */ public File getFileAST(IFile file, String fileContents){ File result = null; try{ result = getFileAST(new BufferedReader(new StringReader(fileContents))); } catch (Exception e) { throw new BuildException(e); } fileLRUCache.put(file, result); return result; } private File getFileAST(Reader reader) { ErrorCorrectingParser parser = new ErrorCorrectingParser(new Lexer(reader)); return (File)parser.parse().value; } public Part getPartAST(IFile declaringFile, String partName) { File file = getFileAST(declaringFile); return getPartAST(file, declaringFile, partName); } public Part getPartAST(File file, IFile declaringFile, String partName) { List parts = file.getParts(); for(Iterator iter = parts.iterator(); iter.hasNext();) { Part part = (Part) iter.next(); if(NameUtile.equals(part.getIdentifier(), partName)){ Part result = part.clonePart(); doGetPartAST(declaringFile, result); return result; } } throw new BuildException("Part must exist before calling this method"); //$NON-NLS-1$ } protected void doGetPartAST(IFile declaringFile, Part result) { // noop - required by Working copy ast manager } public Node getAST(IFile declaringFile, String partName){ if(NameUtile.equals(Util.getFilePartName(declaringFile), partName)){ return getFilePartAST(declaringFile); }else{ return getPartAST(declaringFile, partName); } } private Node getFilePartAST(IFile declaringFile) { return getFileAST(declaringFile).cloneFilePart(); } public void clear(){ fileLRUCache = new SoftLRUCache(); } }