Commit faf250f9 authored by Christoph Döbber's avatar Christoph Döbber
Browse files

YELLOW + cleanup

parent 1fe68139
/*--------------------------------------------------------------------------+
$Id: codetemplates.xml 1 2011-01-01 00:00:01Z hoelzl $
| |
| Copyright 2012 ForTISS GmbH |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
+--------------------------------------------------------------------------*/
package org.fortiss.af3.component.ui.editor;
import static org.fortiss.af3.component.ui.editor.code.ErrorAnnotation.ERROR_RGB;
import static org.fortiss.af3.component.ui.editor.code.ErrorAnnotation.ERROR_TYPE;
import static org.fortiss.tooling.kernel.ui.util.DataBindingUtils.performComplexTextBinding;
import static org.fortiss.tooling.kernel.ui.util.ObservableUtils.observeValue;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.ITextListener;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.TextEvent;
import org.eclipse.jface.text.source.AnnotationBarHoverManager;
import org.eclipse.jface.text.source.AnnotationModel;
import org.eclipse.jface.text.source.AnnotationPainter;
import org.eclipse.jface.text.source.AnnotationRulerColumn;
import org.eclipse.jface.text.source.CompositeRuler;
import org.eclipse.jface.text.source.IAnnotationAccess;
import org.eclipse.jface.text.source.OverviewRuler;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.actions.TextActionHandler;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.fortiss.af3.component.model.behavior.code.CodePackage;
import org.fortiss.af3.component.model.behavior.code.CodeSpecification;
import org.fortiss.af3.component.ui.editor.code.AnnotationConfiguration;
import org.fortiss.af3.component.ui.editor.code.AnnotationHover;
import org.fortiss.af3.component.ui.editor.code.AnnotationMarkerAccess;
import org.fortiss.af3.component.ui.editor.code.CodeEditorConfiguration;
import org.fortiss.af3.component.ui.editor.code.ColorCache;
import org.fortiss.af3.component.ui.editor.code.ErrorAnnotation;
import org.fortiss.af3.expression.language.Compiler;
import org.fortiss.af3.expression.language.ParseException;
import org.fortiss.af3.expression.language.TypeSystemHandler;
import org.fortiss.af3.expression.ui.databinding.convert.StatementSequenceToStringConverter;
import org.fortiss.af3.expression.ui.databinding.convert.StringToStatementSequenceConverter;
import org.fortiss.af3.expression.ui.databinding.validate.StringToStatementSequenceValidator;
import org.fortiss.af3.project.typesystem.ITypeSystemCompiler;
import org.fortiss.tooling.kernel.ui.extension.base.EditorBase;
import org.fortiss.tooling.kernel.ui.service.IActionService;
/**
* Editor for code specifications.
*
* @author doebber
* @author $Author: hoelzl $
* @version $Rev: 18709 $
* @ConQAT.Rating YELLOW Hash: 319F9DEB6C08E66DB58946A6D74B1DCE
*/
public class CodeSpecificationEditor extends EditorBase<CodeSpecification> {
/** Stores the forms toolkit. */
private final FormToolkit formToolkit = new FormToolkit(Display.getDefault());
/** Stores the scrolled form. */
private ScrolledForm scrldfrmCodeSpecification;
/** Stores the source viewer. */
private SourceViewer codeViewer;
/** Stores the text action handler. */
private TextActionHandler textActionHandler;
/** Stores the annotation model. */
private AnnotationModel annotationModel = new AnnotationModel();
/** Returns annotationModel. */
public AnnotationModel getAnnotationModel() {
return annotationModel;
}
/** Stores the type system compiler instance. */
private final ITypeSystemCompiler compiler = TypeSystemHandler.INSTANCE.getTypeSystemCompiler();
/** Stores the pattern applied to the error messages. */
private final Pattern pattern = Pattern.compile("line (\\d*):(\\d*) (.*)");
/** {@inheritDoc} */
@Override
public void createPartControl(Composite parent) {
parent.setLayout(new FillLayout());
scrldfrmCodeSpecification = formToolkit.createScrolledForm(parent);
formToolkit.paintBordersFor(scrldfrmCodeSpecification);
scrldfrmCodeSpecification.setText("Code Specification");
scrldfrmCodeSpecification.getBody().setLayout(new FillLayout(SWT.HORIZONTAL));
formToolkit.decorateFormHeading(scrldfrmCodeSpecification.getForm());
createCodeEditor(scrldfrmCodeSpecification.getBody());
updateModel();
}
/** Creates the actual editor. */
@SuppressWarnings("deprecation")
private void createCodeEditor(Composite parent) {
IAnnotationAccess fAnnotationAccess = new AnnotationMarkerAccess();
// necessary magic
ColorCache cc = new ColorCache();
// rulers
CompositeRuler fCompositeRuler = new CompositeRuler();
OverviewRuler fOverviewRuler = new OverviewRuler(fAnnotationAccess, 12, cc);
AnnotationRulerColumn annotationRuler =
new AnnotationRulerColumn(annotationModel, 16, fAnnotationAccess);
fCompositeRuler.setModel(annotationModel);
fOverviewRuler.setModel(annotationModel);
// annotation ruler is decorating our composite ruler
fCompositeRuler.addDecorator(0, annotationRuler);
// add what types are show on the different rulers
annotationRuler.addAnnotationType(ERROR_TYPE);
fOverviewRuler.addAnnotationType(ERROR_TYPE);
fOverviewRuler.addHeaderAnnotationType(ERROR_TYPE);
// set what layer this type is on
fOverviewRuler.setAnnotationTypeLayer(ERROR_TYPE, 3);
// set what color is used on the overview ruler for the type
fOverviewRuler.setAnnotationTypeColor(ERROR_TYPE,
new Color(Display.getDefault(), ERROR_RGB));
// create the actual source viewer
codeViewer =
new SourceViewer(parent, fCompositeRuler, fOverviewRuler, true, SWT.MULTI |
SWT.V_SCROLL | SWT.H_SCROLL);
codeViewer.setDocument(new Document(), annotationModel);
// hover manager that shows text when hovering
AnnotationBarHoverManager fAnnotationHoverManager =
new AnnotationBarHoverManager(fCompositeRuler, codeViewer, new AnnotationHover(
annotationModel), new AnnotationConfiguration());
fAnnotationHoverManager.install(annotationRuler.getControl());
// to paint the annotations
AnnotationPainter ap = new AnnotationPainter(codeViewer, fAnnotationAccess);
ap.addAnnotationType(ERROR_TYPE);
ap.setAnnotationTypeColor(ERROR_TYPE, new Color(Display.getDefault(), ERROR_RGB));
codeViewer.addPainter(ap);
// setup the editor concerning syntax highlighting and content assist
codeViewer.configure(getSourceViewerConfig());
// set code font
codeViewer.getTextWidget().setFont(new Font(Display.getCurrent(), getOSSpecificCodeFont()));
codeViewer.addTextListener(new ITextListener() {
@Override
public void textChanged(TextEvent event) {
if(event.getDocumentEvent() != null) {
showErrors();
}
}
});
}
/**
* Creates the SourceViewerConfiguration containing the setup for both syntax highlighting and
* content assist.
*/
private SourceViewerConfiguration getSourceViewerConfig() {
return new CodeEditorConfiguration(this);
}
/** Returns the font specific for the used operation system. */
private FontData getOSSpecificCodeFont() {
String os = System.getProperty("os.name");
String font = "Courier";
if(os.toLowerCase().contains("mac")) {
font = "Monaco";
} else if(os.toLowerCase().contains("windows")) {
font = "Consolas";
} else if(os.toLowerCase().contains("linux")) {
font = "Monospace";
}
return new FontData(font, 11, SWT.NORMAL);
}
/** Displays the actual error in the editor. */
public void showErrors() {
String code = codeViewer.getTextWidget().getText();
annotationModel.removeAllAnnotations();
try {
((Compiler)compiler).compileStatementTerm(code);
} catch(ParseException e) {
for(String msg : e.getMessages()) {
Matcher matcher = pattern.matcher(msg);
boolean matchFound = matcher.find();
if(matchFound) {
int line = Integer.parseInt(matcher.group(1));
int lineOffset = Integer.parseInt(matcher.group(2));
String errorMsg = matcher.group(3);
ErrorAnnotation errorAnnotation = new ErrorAnnotation(line, errorMsg);
codeViewer.getAnnotationModel().addAnnotation(errorAnnotation,
findErrorRange(code, line, lineOffset));
}
}
}
}
/**
* Returns the range of the error from the position in the string based on the given line number
* and the line-relative offset to the next newline or end of string.
*/
private Position findErrorRange(String string, int line, int lineOffset) {
int start = 0;
int end = 0;
for(int i = 1; i < line; i++) {
start += findNewLine(string, start);
}
start += lineOffset;
end = findNewLine(string, start);
return new Position(start, end);
}
/**
* Utility method returning the first occurrence of a newline (or the end of the string)
* relative to the given offset.
*/
private int findNewLine(String string, int offset) {
int newline = string.substring(offset + 1).indexOf('\n');
if(newline == -1) {
newline = string.substring(offset + 1).length() - 1;
}
return newline + 2;
}
/** {@inheritDoc} */
@Override
public void registerGlobalActions(IActionBars bars) {
textActionHandler = new TextActionHandler(bars);
// FIXME
// textActionHandler.addText(codeViewer.getTextWidget());
IActionService.INSTANCE.registerGlobalUndoRedoActions(bars);
}
/** {@inheritDoc} */
@Override
public void dispose() {
textActionHandler.dispose();
super.dispose();
}
/** Performs the text to model binding. */
private void updateModel() {
IObservableValue modelObservable =
observeValue(getEditedObject(), CodePackage.Literals.CODE_SPECIFICATION__BODY);
performComplexTextBinding(dbc, codeViewer.getTextWidget(), modelObservable,
new StatementSequenceToStringConverter(true),
new StringToStatementSequenceConverter(), new StringToStatementSequenceValidator(
getEditedObject()), null);
}
}
......@@ -27,7 +27,7 @@ import org.fortiss.tooling.kernel.ui.extension.IModelEditorBinding;
* @author doebber
* @author $Author: hoelzl $
* @version $Rev: 18709 $
* @ConQAT.Rating GREEN Hash: 8C32F4F731819CAA424194AE3FE26D61
* @ConQAT.Rating YELLOW Hash: 4DA3F85657E5D26592C83B1DA61CFA90
*/
public class CodeSpecificationEditorBinding implements
IModelEditorBinding<CodeSpecification> {
......@@ -35,7 +35,7 @@ public class CodeSpecificationEditorBinding implements
/** {@inheritDoc} */
@Override
public Class<? extends IEditorPart> getEditorClass() {
return CodeSpecificationEditorBackend.class;
return CodeSpecificationEditor.class;
}
/** {@inheritDoc} */
......
/*--------------------------------------------------------------------------+
$Id$
| |
| Copyright 2012 ForTISS GmbH |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
+--------------------------------------------------------------------------*/
package org.fortiss.af3.component.ui.editor.code;
import org.eclipse.jface.text.DefaultInformationControl;
import org.eclipse.jface.text.IInformationControl;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.swt.widgets.Shell;
/**
* Class acting as annotation configuration.
*
* @author doebber
* @author $Author$
* @version $Rev$
* @ConQAT.Rating YELLOW Hash: 54062FB12A51A9216A19506D914BDCAC
*/
public class AnnotationConfiguration implements IInformationControlCreator {
/** {@inheritDoc} */
@Override
public IInformationControl createInformationControl(Shell shell) {
return new DefaultInformationControl(shell);
}
}
......@@ -28,21 +28,28 @@ import org.eclipse.jface.text.source.AnnotationModel;
import org.eclipse.jface.text.source.IAnnotationHover;
import org.eclipse.jface.text.source.ISourceViewer;
// annotation hover manager
/**
* Class acting as annotation hover manager.
*
* @author doebber
* @author $Author$
* @version $Rev$
* @ConQAT.Rating YELLOW Hash: 521EC14844EC642DA6392776FC81AA8B
*/
public class AnnotationHover implements IAnnotationHover, ITextHover {
/** */
/** Stores the {@link AnnotationModel}. */
private final AnnotationModel model;
/**
* @param codeSpecificationEditorBackend
*/
/** Constructor. */
public AnnotationHover(AnnotationModel model) {
this.model = model;
}
/** {@inheritDoc} */
@Override
public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) {
Iterator ite = model.getAnnotationIterator();
Iterator<?> ite = model.getAnnotationIterator();
ArrayList<String> all = new ArrayList<String>();
......@@ -61,10 +68,14 @@ public class AnnotationHover implements IAnnotationHover, ITextHover {
return total.toString();
}
/** {@inheritDoc} */
@Override
public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
return null;
}
/** {@inheritDoc} */
@Override
public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
return null;
}
......
......@@ -26,6 +26,14 @@ import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;
/**
* Class providing annotation marker access.
*
* @author doebber
* @author $Author$
* @version $Rev$
* @ConQAT.Rating YELLOW Hash: 2034A44A9640D6BCE574EC05F036461D
*/
public class AnnotationMarkerAccess implements IAnnotationAccess, IAnnotationAccessExtension {
/** {@inheritDoc} */
@Override
......
/*--------------------------------------------------------------------------+
$Id$
| |
| Copyright 2012 ForTISS GmbH |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
+--------------------------------------------------------------------------*/
package org.fortiss.af3.component.ui.editor.code;
import static org.fortiss.af3.component.ui.utils.ComponentFieldAssistUtils.getInputPortNames;
import static org.fortiss.af3.component.ui.utils.ComponentFieldAssistUtils.getOutputPortNames;
import static org.fortiss.af3.expression.ui.utils.ExpressionFieldAssistUtils.getAllConstructors;
import static org.fortiss.af3.expression.ui.utils.ExpressionFieldAssistUtils.getAllConstructorsWithoutBrackets;
import static org.fortiss.af3.expression.ui.utils.ExpressionFieldAssistUtils.getFunctions;
import static org.fortiss.af3.expression.ui.utils.ExpressionFieldAssistUtils.getPrimitiveTypes;
import static org.fortiss.af3.expression.ui.utils.ExpressionFieldAssistUtils.getPrimitiveValues;
import static org.fortiss.af3.expression.ui.utils.ExpressionFieldAssistUtils.getUsefulExpressions;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.TextAttribute;
import org.eclipse.jface.text.contentassist.CompletionProposal;
import org.eclipse.jface.text.contentassist.ContentAssistant;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.jface.text.contentassist.IContextInformationValidator;
import org.eclipse.jface.text.presentation.IPresentationReconciler;
import org.eclipse.jface.text.presentation.PresentationReconciler;
import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
import org.eclipse.jface.text.rules.IRule;
import org.eclipse.jface.text.rules.IToken;
import org.eclipse.jface.text.rules.ITokenScanner;
import org.eclipse.jface.text.rules.IWordDetector;
import org.eclipse.jface.text.rules.RuleBasedScanner;
import org.eclipse.jface.text.rules.Token;
import org.eclipse.jface.text.rules.WordRule;
import org.eclipse.jface.text.source.IAnnotationHover;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.fortiss.af3.component.ui.editor.CodeSpecificationEditor;
import org.fortiss.af3.component.ui.utils.CodeUtils;
import org.fortiss.tooling.base.ui.fieldassist.FieldAssistImageRegistry;
/**
*
* @author doebber
* @author $Author$
* @version $Rev$
* @ConQAT.Rating YELLOW Hash: 4B9D6DF1E19BD1C87DCA808C3E6F6D4A
*/
public class CodeEditorConfiguration extends SourceViewerConfiguration {
/** Stores the actual editor object. */
private CodeSpecificationEditor editor;
/** Constructor. */
public CodeEditorConfiguration(CodeSpecificationEditor editor) {
this.editor = editor;
}
/** Color constant used to display code dark red. */
private Color DARK_RED = new Color(null, 128, 0, 0);
/** Color constant used to display code dark blue. */
private Color DARK_BLUE = new Color(null, 0, 0, 128);
/** {@inheritDoc} */
@Override
public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {
PresentationReconciler reconciler = new PresentationReconciler();
DefaultDamagerRepairer dr = new DefaultDamagerRepairer(getScanner());
reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
return reconciler;
}
/** Returns the scanner. */
private ITokenScanner getScanner() {
return getScannerForSyntaxHighlighting();
}
/** Returns the annotation hover. */
@Override
public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) {
return new AnnotationHover(editor.getAnnotationModel());
}
/** Returns the content assistant. */
@Override
public org.eclipse.jface.text.contentassist.IContentAssistant getContentAssistant(
ISourceViewer sourceViewer) {
ContentAssistant assistant = new ContentAssistant();
IContentAssistProcessor proc = new IContentAssistProcessor() {
/** {@inheritDoc} */
@Override
public String getErrorMessage() {
// nothing to do
return null;
}
/** {@inheritDoc} */
@Override
public IContextInformationValidator getContextInformationValidator() {
// nothing to do
return null;
}
/** {@inheritDoc} */
@Override
public char[] getContextInformationAutoActivationCharacters() {
// nothing to do
return null;
}
/** {@inheritDoc} */
@Override
public char[] getCompletionProposalAutoActivationCharacters() {
String allLetters = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_";
return allLetters.toCharArray();
}
/** {@inheritDoc} */
@Override