/******************************************************************************* * Copyright (c) 2006, 2009 Zend Corporation and IBM Corporation. * 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: * William Candillon {wcandillon@gmail.com} - Initial implementation *******************************************************************************/ package org.eclipse.php.internal.ui.editor.highlighter; import java.io.IOException; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import org.eclipse.dltk.core.ISourceModule; import org.eclipse.dltk.core.ISourceRange; import org.eclipse.dltk.core.ModelException; import org.eclipse.dltk.internal.core.BufferManager; import org.eclipse.dltk.internal.ui.editor.DocumentAdapter; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.text.Position; import org.eclipse.php.core.ast.nodes.ASTNode; import org.eclipse.php.core.ast.nodes.Program; import org.eclipse.php.internal.ui.editor.SemanticHighlightingStyle; import org.eclipse.php.internal.ui.preferences.PreferenceConstants; import org.eclipse.php.ui.editor.SharedASTProvider; import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion; import org.eclipse.wst.sse.ui.ISemanticHighlighting; import org.eclipse.wst.sse.ui.ISemanticHighlightingExtension2; public abstract class AbstractSemanticHighlighting implements ISemanticHighlighting, ISemanticHighlightingExtension2, Comparable<AbstractSemanticHighlighting> { private ISourceModule sourceModule = null; private SemanticHighlightingStyle style = new SemanticHighlightingStyle(getPreferenceKey()); private List<Position> list; private final String preferenceKey = this.getClass().getName(); public AbstractSemanticHighlighting() { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=333322 (points 9 and // 10): // SemanticHighlightingManager#loadSemanticHighlightings() creates // highlighters by doing // elements[i].createExecutableExtension(CLASS_ATTR) // so we can't do any additional configuration outside the constructor. initDefaultPreferences(); } public String getPreferenceKey() { return preferenceKey; } public SemanticHighlightingStyle getStyle() { return style; } public ISourceModule getSourceModule() { if (sourceModule == null) { throw new IllegalStateException("Source module cannot be null"); //$NON-NLS-1$ } return sourceModule; } protected AbstractSemanticHighlighting highlight(ISourceRange range) { if (range == null) { throw new IllegalArgumentException("Range cannot be null"); //$NON-NLS-1$ } return highlight(range.getOffset(), range.getLength()); } protected AbstractSemanticHighlighting highlight(ASTNode node) { if (node == null) { throw new IllegalArgumentException("Node cannot be null"); //$NON-NLS-1$ } return highlight(node.getStart(), node.getLength()); } protected AbstractSemanticHighlighting highlight(int start, int length) { if (list == null) { throw new IllegalStateException(); } list.add(new Position(start, length)); return this; } public Position[] consumes(Program program) { if (program != null) { program.getAST().getBindingResolver().startBindingSession(); list = new ArrayList<>(); sourceModule = program.getSourceModule(); AbstractSemanticApply apply = getSemanticApply(); program.accept(apply); program.getAST().getBindingResolver().stopBindingSession(); return list.toArray(new Position[list.size()]); } return new Position[0]; } @Override public Position[] consumes(IStructuredDocumentRegion region) { if (region.getStart() == 0) { Program program = getProgram(region); return consumes(program); } return new Position[0]; } protected Program getProgram(final IStructuredDocumentRegion region) {// region.getParentDocument().get() sourceModule = null; // resolve current sourceModule Enumeration<?> openBuffers = BufferManager.getDefaultBufferManager().getOpenBuffers(); while (openBuffers.hasMoreElements()) { Object nextElement = openBuffers.nextElement(); if (nextElement instanceof DocumentAdapter) { DocumentAdapter adapt = (DocumentAdapter) nextElement; if (adapt.getDocument().equals(region.getParentDocument()) && adapt.getOwner() instanceof ISourceModule) { sourceModule = (ISourceModule) adapt.getOwner(); break; } } } // resolve AST Program program = null; if (sourceModule != null) { try { // Wait active_only. Sometimes highlighters are called without // reconciling program = SharedASTProvider.getAST(sourceModule, SharedASTProvider.WAIT_YES, null); } catch (ModelException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } return program; } @Override public String getBoldPreferenceKey() { return PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + preferenceKey + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_BOLD_SUFFIX; } @Override public String getColorPreferenceKey() { return PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + preferenceKey + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_COLOR_SUFFIX; } @Override public String getBackgroundColorPreferenceKey() { return PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + preferenceKey + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_BGCOLOR_SUFFIX; } @Override public String getEnabledPreferenceKey() { return PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + preferenceKey + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_ENABLED_SUFFIX; } @Override public String getItalicPreferenceKey() { return PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + preferenceKey + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_ITALIC_SUFFIX; } @Override public IPreferenceStore getPreferenceStore() { return PreferenceConstants.getPreferenceStore(); } @Override public String getStrikethroughPreferenceKey() { return PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + preferenceKey + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_STRIKETHROUGH_SUFFIX; } @Override public String getUnderlinePreferenceKey() { return PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + preferenceKey + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_UNDERLINE_SUFFIX; } public abstract AbstractSemanticApply getSemanticApply(); protected abstract void initDefaultPreferences(); @Override public int compareTo(AbstractSemanticHighlighting highlighter) { return getPriority() - highlighter.getPriority(); } public int getPriority() { return 100; } }