blob: 0b798e8987d294733e844af994940c41306ed2ed [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2006 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* Contributors:
* Miguel Garcia (Tech Univ Hamburg-Harburg) - customization for EMF Generics
*******************************************************************************/
package org.eclipse.emf.emfatic.ui.redsquiggles;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.emfatic.core.lang.gen.ast.CompUnit;
import org.eclipse.emf.emfatic.core.lang.gen.ast.EmfaticASTNodeVisitor;
import org.eclipse.emf.emfatic.core.lang.gen.ast.MapEntryDecl;
import org.eclipse.emf.emfatic.core.lang.gen.ast.TopLevelDecl;
import org.eclipse.emf.emfatic.ui.editor.EmfaticEditor;
import org.eclipse.gymnast.runtime.core.ast.ASTNode;
import org.eclipse.gymnast.runtime.ui.views.parsetree.IParseTreeChangedListener;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.Position;
import org.eclipse.ui.texteditor.IDocumentProvider;
public class EmfaticCSTChangeListener implements IParseTreeChangedListener {
EmfaticEditor _editor;
public static QualifiedName qnCST = new QualifiedName("de.tuhh.sts.emfatic", "cst");
public static QualifiedName qnAST = new QualifiedName("de.tuhh.sts.emfatic", "ast");
public EmfaticCSTChangeListener(EmfaticEditor editor) {
_editor = editor;
}
/**
* responsible for folding
*/
public void parseTreeChanged(ASTNode[] arg0) {
/*
* TODO arg0 is always null because LDTEditor#setParseRoot gives just
* that instead of its _parseRoot
*/
/*
* see the resource listener EmfaticRedSquiggler for an alternative way
* of listening
*/
IFile emfFile = _editor.getFile();
CompUnit compUnit = (CompUnit) _editor.getParseRoot();
try {
if (emfFile != null) {
emfFile.setSessionProperty(qnCST, compUnit);
emfFile.setSessionProperty(qnAST, null);
}
} catch (CoreException e) {
e.printStackTrace();
}
if (compUnit != null) {
// the ast was set in EmfaticParserDriver#parse()
EPackage rootPackage = compUnit.getAST();
try {
emfFile.setSessionProperty(qnAST, rootPackage);
} catch (CoreException e) {
e.printStackTrace();
}
}
updateFolding();
return;
}
private List<Position> fPositions = new ArrayList<Position>();
private void updateFolding() {
fPositions = new ArrayList<Position>();
CompUnit compUnit = (CompUnit) _editor.getParseRoot();
if (compUnit == null) {
return;
}
new EmfaticASTNodeVisitor() {
public boolean beginVisit(TopLevelDecl tld) {
if (!(tld instanceof MapEntryDecl)) {
int offset = tld.getRangeStart();
int length = tld.getRangeLength();
if (spansSeveralLines(offset, length)) {
fPositions.add(new Position(offset, length));
}
}
return true;
}
/*
* comments (including multiline ones) are eaten up by the lexer,
* there are no productions in the grammar for comments, and thus
* cannot be folded. Once that changes, this is the place to add a
* visitor handler which creates a Position to indicate that region
* can be folded.
*/
}.visit(compUnit.getTopLevelDecls());
_editor.updateFoldingStructure(fPositions);
}
private boolean spansSeveralLines(final int offset, final int length) {
IDocumentProvider dp = _editor.getDocumentProvider();
IDocument doc = dp.getDocument(_editor.getEditorInput());
if (doc != null) {
try {
String[] lines = doc.get(offset, length).split("\n");
boolean res = lines.length > 2;
return res;
} catch (BadLocationException e) {}
}
return false;
}
}