/******************************************************************************* * Copyright © 2000, 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.ui.internal.editor.util; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.Reader; import java.util.Iterator; import java.util.List; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.CoreException; import org.eclipse.edt.compiler.core.ast.AbstractASTVisitor; 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.ide.core.internal.model.BufferManager; import org.eclipse.edt.ide.core.model.IBuffer; import org.eclipse.edt.ide.core.model.IBufferFactory; import org.eclipse.edt.ide.core.model.IEGLFile; import org.eclipse.edt.ide.core.model.document.IEGLDocument; import org.eclipse.edt.ide.ui.internal.editor.DocumentAdapter; import org.eclipse.jface.text.IDocument; public class EGLModelUtility { /* * return the production node for the nested part in eglPart which matches part naame * This currently only works for functions in programs, page handlers, and libraries. * It can easily be modified for forms in form groups if necessary */ public static Node getNestedPartNode(IEGLDocument document, final int documentOffset) { File fileAST = document.getNewModelEGLFile(); final Node[] newNestedNode = new Node[]{null}; fileAST.accept(new AbstractASTVisitor(){ public boolean visit(org.eclipse.edt.compiler.core.ast.NestedFunction nestedFunction) { visitNestedPart(nestedFunction); return false; }; private void visitNestedPart(Node nestedNode) { if(documentOffset >= nestedNode.getOffset() && documentOffset <= nestedNode.getOffset() + nestedNode.getLength()) newNestedNode[0] = nestedNode; } }); return newNestedNode[0]; } /* * Get the top level part associated with the cursor position * If not in a top level part null is returned */ public static Part getPartNode(IEGLDocument document, int documentOffset) { Part eglPart = null; List eglParts = document.getNewModelEGLFile().getParts(); Iterator iter = eglParts.iterator(); while (iter.hasNext()) { eglPart = (Part) iter.next(); int offset = eglPart.getOffset(); int length = eglPart.getLength(); if (documentOffset < offset) return null; if (documentOffset >= offset && documentOffset <= offset + length){ return eglPart; } } return null; } /** * this is the equvalent replacement for the old EGLCore.getEGLFile() T-model to pgm model conversion * * The AST Root node return is from saved file version, not live info * * @param element * @return the File root node of the T-modle IEGLElement * @throws CoreException * @throws * @throws */ public static File getEGLFileAST(IEGLFile eglfile, IBufferFactory factory) throws Exception { IEGLFile workingCopy = null; try{ if(factory == null) factory = BufferManager.getDefaultBufferManager().getDefaultBufferFactory(); workingCopy = (IEGLFile)(eglfile.getSharedWorkingCopy(null, factory, null)); IBuffer buf = workingCopy.getBuffer(); if(buf.hasUnsavedChanges()) { //use the saved file IFile file = (IFile)(eglfile.getUnderlyingResource()); ErrorCorrectingParser newParser; int whitespacemask = ErrorCorrectingParser.RETURN_BLOCK_COMMENT | ErrorCorrectingParser.RETURN_LINE_COMMENT | ErrorCorrectingParser.RETURN_LINEBREAKS; Reader reader = new BufferedReader(new InputStreamReader(file.getContents(true), file.getCharset())); newParser = new ErrorCorrectingParser(new Lexer(reader), whitespacemask); File fileRootNode = (File)(newParser.parse().value); return fileRootNode; } else //use the cached ast tree from document { if(buf instanceof DocumentAdapter) { IDocument doc = ((DocumentAdapter)buf).getDocument(); if(doc instanceof IEGLDocument) { IEGLDocument egldoc = (IEGLDocument)doc; return egldoc.getNewModelEGLFile(); } } } } finally{ if(workingCopy != null) workingCopy.destroy(); //release the workingCopy to decrement the count } return null; } }