diff --git a/.project b/.project
index 0b76a40ba80..666006c4305 100644
--- a/.project
+++ b/.project
@@ -1,17 +1,17 @@
-
-
- processing-head
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
-
- org.eclipse.jdt.core.javanature
-
-
+
+
+ processing-head
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/app/.classpath b/app/.classpath
index 8d33d06788f..0f1066dfec9 100644
--- a/app/.classpath
+++ b/app/.classpath
@@ -31,5 +31,8 @@
+
+
+
diff --git a/app/.project b/app/.project
index 69a82c3d004..78e91ccbbfa 100644
--- a/app/.project
+++ b/app/.project
@@ -1,17 +1,17 @@
-
-
- processing
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
-
- org.eclipse.jdt.core.javanature
-
-
+
+
+ processing
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/app/.settings/org.eclipse.jdt.core.prefs b/app/.settings/org.eclipse.jdt.core.prefs
index 4b64040da73..462c9daed55 100644
--- a/app/.settings/org.eclipse.jdt.core.prefs
+++ b/app/.settings/org.eclipse.jdt.core.prefs
@@ -1,20 +1,11 @@
eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
-org.eclipse.jdt.core.compiler.compliance=1.6
-org.eclipse.jdt.core.compiler.debug.lineNumber=generate
-org.eclipse.jdt.core.compiler.debug.localVariable=generate
-org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
-org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
org.eclipse.jdt.core.compiler.problem.deprecation=warning
org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
@@ -62,7 +53,6 @@ org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=di
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
-org.eclipse.jdt.core.compiler.source=1.6
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
diff --git a/app/build.xml b/app/build.xml
index 4c20976b60d..1119d468738 100644
--- a/app/build.xml
+++ b/app/build.xml
@@ -7,6 +7,7 @@
+
diff --git a/app/lib/cplus-libparser-0.0.1.jar b/app/lib/cplus-libparser-0.0.1.jar
new file mode 100755
index 00000000000..8d9122aeb7e
Binary files /dev/null and b/app/lib/cplus-libparser-0.0.1.jar differ
diff --git a/app/lib/rsyntax-autocomplete-2.6.0-SNAPSHOT.jar b/app/lib/rsyntax-autocomplete-2.6.0-SNAPSHOT.jar
new file mode 100755
index 00000000000..12beccfef93
Binary files /dev/null and b/app/lib/rsyntax-autocomplete-2.6.0-SNAPSHOT.jar differ
diff --git a/app/src/ArduinoIDE.java b/app/src/ArduinoIDE.java
new file mode 100755
index 00000000000..ad7adcabca8
--- /dev/null
+++ b/app/src/ArduinoIDE.java
@@ -0,0 +1,46 @@
+/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
+
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ * Copyright 2015 Arduino LLC
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
+import processing.app.Base;
+
+/**
+ * Arduino IDE Launcher class
+ * @author Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ * @date 23/01/2015
+ */
+public class ArduinoIDE {
+
+ public static void main(String[] args) throws Exception {
+ Base.main(args);
+ }
+
+}
diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java
index 6f31a2b7281..e2cefd4e0d2 100644
--- a/app/src/processing/app/Base.java
+++ b/app/src/processing/app/Base.java
@@ -36,11 +36,14 @@
import cc.arduino.utils.Progress;
import cc.arduino.view.*;
import cc.arduino.view.Event;
+
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Collections2;
+
import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.lang3.StringUtils;
+
import processing.app.debug.TargetBoard;
import processing.app.debug.TargetPackage;
import processing.app.debug.TargetPlatform;
@@ -64,10 +67,6 @@
import java.io.*;
import java.util.*;
import java.util.List;
-import java.util.logging.Handler;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
import static processing.app.I18n._;
@@ -146,8 +145,6 @@ static public void guardedMain(String args[]) throws Exception {
BaseNoGui.initLogger();
- initLogger();
-
BaseNoGui.initPlatform();
BaseNoGui.getPlatform().init();
@@ -226,35 +223,6 @@ static public void guardedMain(String args[]) throws Exception {
INSTANCE = new Base(args);
}
-
- static public void initLogger() {
- Handler consoleHandler = new ConsoleLogger();
- consoleHandler.setLevel(Level.ALL);
- consoleHandler.setFormatter(new LogFormatter("%1$tl:%1$tM:%1$tS [%4$7s] %2$s: %5$s%n"));
-
- Logger globalLogger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
- globalLogger.setLevel(consoleHandler.getLevel());
-
- // Remove default
- Handler[] handlers = globalLogger.getHandlers();
- for(Handler handler : handlers) {
- globalLogger.removeHandler(handler);
- }
- Logger root = Logger.getLogger("");
- handlers = root.getHandlers();
- for(Handler handler : handlers) {
- root.removeHandler(handler);
- }
-
- globalLogger.addHandler(consoleHandler);
-
- Logger.getLogger("cc.arduino.packages.autocomplete").setParent(globalLogger);
- Logger.getLogger("br.com.criativasoft.cpluslibparser").setParent(globalLogger);
- Logger.getLogger(Base.class.getPackage().getName()).setParent(globalLogger);
-
- }
-
-
static protected void setCommandLine() {
commandLine = true;
}
diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java
index e9e987c2f67..cd6c6c08bf3 100644
--- a/app/src/processing/app/Editor.java
+++ b/app/src/processing/app/Editor.java
@@ -22,14 +22,20 @@
package processing.app;
+import br.com.criativasoft.cpluslibparser.LibraryIndex;
+import br.com.criativasoft.cpluslibparser.metadata.TElementLocation;
+import br.com.criativasoft.cpluslibparser.metadata.TError;
+import br.com.criativasoft.cpluslibparser.metadata.TLibrary;
import cc.arduino.packages.MonitorFactory;
-
import cc.arduino.view.StubMenuListener;
import cc.arduino.view.findreplace.FindReplace;
+
import com.google.common.base.Predicate;
import com.jcraft.jsch.JSchException;
+
import jssc.SerialPortException;
import processing.app.debug.*;
+import processing.app.debug.Compiler;
import processing.app.forms.PasswordAuthorizationDialog;
import processing.app.helpers.OSUtils;
import processing.app.helpers.PreferencesMapException;
@@ -62,6 +68,7 @@
import cc.arduino.packages.BoardPort;
import cc.arduino.packages.Uploader;
+import cc.arduino.packages.autocomplete.SketchCompletionProvider;
import cc.arduino.packages.uploaders.SerialUploader;
/**
@@ -148,6 +155,7 @@ public boolean apply(Sketch sketch) {
Sketch sketch;
private EditorLineStatus lineStatus;
+ SyntaxErrorMarker errorMarker;
//JEditorPane editorPane;
@@ -204,6 +212,11 @@ public void windowClosing(WindowEvent e) {
addWindowListener(new WindowAdapter() {
public void windowActivated(WindowEvent e) {
base.handleActivated(Editor.this);
+
+ if(sketch != null){
+ LibraryIndex.setContextCache(sketch.getSketchData().getLibraryCacheContext());
+ }
+
}
// added for 1.0.5
@@ -995,6 +1008,7 @@ private String findClassInZipFile(String base, File file) {
private SketchTextArea createTextArea() throws IOException {
final SketchTextArea textArea = new SketchTextArea(base.getPdeKeywords());
+ textArea.addParser(new TokenErrorMarker(textArea));
textArea.setFocusTraversalKeysEnabled(false);
textArea.requestFocusInWindow();
textArea.setMarkOccurrences(PreferencesData.getBoolean("editor.advanced"));
@@ -1756,7 +1770,7 @@ protected void setCode(final SketchCodeDocument codeDoc) {
if(codeDoc.getUndo() == null){
codeDoc.setUndo(new LastUndoableEditAwareUndoManager(textarea, this));
document.addUndoableEditListener(codeDoc.getUndo());
- }
+ }
// Update the document object that's in use
textarea.switchDocument(document, codeDoc.getUndo());
@@ -1767,6 +1781,8 @@ protected void setCode(final SketchCodeDocument codeDoc) {
textarea.select(codeDoc.getSelectionStart(), codeDoc.getSelectionStop());
textarea.requestFocus(); // get the caret blinking
+
+ if(errorMarker != null) errorMarker.setCurrentCode(codeDoc.getCode());
final int position = codeDoc.getScrollPosition();
@@ -1951,6 +1967,7 @@ public BuildHandler(boolean verbose, boolean saveHex) {
public void run() {
try {
textarea.removeAllLineHighlights();
+ errorMarker.removeAll();
sketch.prepare();
sketch.build(verbose, saveHex);
statusNotice(_("Done compiling."));
@@ -2184,6 +2201,18 @@ protected boolean handleOpenInternal(File sketchFile) {
try {
sketch = new Sketch(this, file);
+
+ LibraryIndex.setContextCache(sketch.getSketchData().getLibraryCacheContext());
+
+ // This needs to be after the ' LibraryIndex.setContextCache' for listeners work properly (on SketchCompletionProvider)
+ textarea.setupAutoComplete(new SketchCompletionProvider(sketch.getSketchData()));
+
+ // This needs to be after the ' LibraryIndex.setContextCache' for listeners work properly
+ if(errorMarker == null){
+ errorMarker = new SyntaxErrorMarker(textarea);
+ textarea.addParser(errorMarker);
+ }
+
} catch (IOException e) {
Base.showWarning(_("Error"), _("Could not create the sketch."), e);
return false;
@@ -2659,39 +2688,57 @@ public void statusError(String what) {
*/
public void statusError(Exception e) {
e.printStackTrace();
-// if (e == null) {
-// System.err.println("Editor.statusError() was passed a null exception.");
-// return;
-// }
if (e instanceof RunnerException) {
RunnerException re = (RunnerException) e;
- if (re.hasCodeIndex()) {
- sketch.setCurrentCode(re.getCodeIndex());
- }
- if (re.hasCodeLine()) {
- int line = re.getCodeLine();
- // subtract one from the end so that the \n ain't included
- if (line >= textarea.getLineCount()) {
- // The error is at the end of this current chunk of code,
- // so the last line needs to be selected.
- line = textarea.getLineCount() - 1;
- if (getLineText(line).length() == 0) {
- // The last line may be zero length, meaning nothing to select.
- // If so, back up one more line.
- line--;
+
+ if (re.getErrors() != null && ! re.getErrors().isEmpty()) {
+
+ List errors = re.getErrors();
+
+ for (CompilerError compilerError : errors) {
+
+ sketch.setCurrentCode(compilerError.getFileName());
+
+ int line = compilerError.getLine();
+ // subtract one from the end so that the \n ain't included
+ if (line >= textarea.getLineCount()) {
+ // The error is at the end of this current chunk of code,
+ // so the last line needs to be selected.
+ line = textarea.getLineCount() - 1;
+ if (getLineText(line).length() == 0) {
+ // The last line may be zero length, meaning nothing to select.
+ // If so, back up one more line.
+ line--;
+ }
}
- }
- if (line < 0 || line >= textarea.getLineCount()) {
- System.err.println(I18n.format(_("Bad error line: {0}"), line));
- } else {
- try {
- textarea.addLineHighlight(line, new Color(1, 0, 0, 0.2f));
- textarea.setCaretPosition(textarea.getLineStartOffset(line));
- } catch (BadLocationException e1) {
- e1.printStackTrace();
+ if (line < 0 || line >= textarea.getLineCount()) {
+ System.err.println(I18n.format(_("Bad error line: {0}"), line));
+ } else {
+ try {
+ // textarea.addLineHighlight(line, new Color(1, 0, 0, 0.2f));
+ textarea.setCaretPosition(textarea.getLineStartOffset(line));
+
+ TLibrary metadata = sketch.getSketchData().getSketchMetadata();
+ int startOffset = textarea.getLineStartOffset(line);
+ int endOffset = textarea.getLineEndOffset(line);
+ String path = sketch.getCurrentCode().getFile().getPath();
+
+ TError error = new TError(compilerError.getMessage(), TError.COMPILER_ERROR);
+ error.setLocation(new TElementLocation(path, startOffset, endOffset - startOffset));
+ errorMarker.addError(error);
+ textarea.forceReparsing(errorMarker);
+
+ if(metadata != null){
+ metadata.getErrors().add(error);
+ }
+ } catch (BadLocationException e1) {
+ e1.printStackTrace();
+ }
}
+
}
+
}
}
diff --git a/app/src/processing/app/EditorListener.java b/app/src/processing/app/EditorListener.java
index cbd082cfcad..5e6246461ca 100644
--- a/app/src/processing/app/EditorListener.java
+++ b/app/src/processing/app/EditorListener.java
@@ -5,7 +5,13 @@
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
+import javax.swing.text.BadLocationException;
+
+import org.fife.ui.rsyntaxtextarea.RSyntaxUtilities;
+import org.fife.ui.rsyntaxtextarea.Token;
+
import processing.app.syntax.SketchTextArea;
+import cc.arduino.packages.autocomplete.SketchCompletionProvider;
public class EditorListener implements KeyListener {
@@ -67,7 +73,26 @@ public void keyPressed(KeyEvent event) {
// int line = textarea.getCaretLineNumber();
// textarea.setActiveLineRange(line, line + 3);
// }
-
+
+ // Generate New Variable
+ if (event.isAltDown() && code == KeyEvent.VK_ENTER) {
+
+ int line = textarea.getCaretLineNumber();
+
+ Token tokenListForLine = textarea.getTokenListForLine(line);
+ int start = RSyntaxUtilities.getNextImportantToken(tokenListForLine, textarea, line).getOffset();
+ int end = textarea.getLineEndOffsetOfCurrentLine();
+
+ try {
+ String expression = textarea.getText(start, end - start);
+ SketchCompletionProvider provider = textarea.getCompletionProvider();
+ provider.generateNewVariableFor(expression, start);
+
+
+
+ } catch (BadLocationException e) {}
+
+ }
}
@Override
diff --git a/app/src/processing/app/LastUndoableEditAwareUndoManager.java b/app/src/processing/app/LastUndoableEditAwareUndoManager.java
old mode 100644
new mode 100755
diff --git a/app/src/processing/app/Sketch.java b/app/src/processing/app/Sketch.java
index 9cae9d25e04..feec97f0b33 100644
--- a/app/src/processing/app/Sketch.java
+++ b/app/src/processing/app/Sketch.java
@@ -997,6 +997,7 @@ public void setCurrentCode(int which, boolean forceUpdate) {
current = (SketchCodeDocument) data.getCode(which).getMetadata();
currentIndex = which;
+ data.setCurrentCode(current.getCode());
editor.setCode(current);
editor.header.rebuild();
@@ -1375,6 +1376,9 @@ public boolean isUntitled() {
return editor.untitled;
}
+ public SketchData getSketchData() {
+ return data;
+ }
// .................................................................
diff --git a/app/src/processing/app/SketchCodeDocument.java b/app/src/processing/app/SketchCodeDocument.java
index 681f0af9151..f8bf711b656 100644
--- a/app/src/processing/app/SketchCodeDocument.java
+++ b/app/src/processing/app/SketchCodeDocument.java
@@ -7,7 +7,7 @@
import javax.swing.text.Document;
import javax.swing.undo.UndoManager;
-public class SketchCodeDocument implements DocumentListener{
+public class SketchCodeDocument implements DocumentListener, SketchDocumentProvider{
private SketchCode code;
private Sketch sketch;
diff --git a/app/src/processing/app/syntax/SketchTextArea.java b/app/src/processing/app/syntax/SketchTextArea.java
index f31a45ab39a..5060510e1ca 100644
--- a/app/src/processing/app/syntax/SketchTextArea.java
+++ b/app/src/processing/app/syntax/SketchTextArea.java
@@ -30,25 +30,12 @@
package processing.app.syntax;
-import org.apache.commons.compress.utils.IOUtils;
-import org.fife.ui.rsyntaxtextarea.*;
-import org.fife.ui.rsyntaxtextarea.Theme;
-import org.fife.ui.rsyntaxtextarea.Token;
-import org.fife.ui.rsyntaxtextarea.focusabletip.FocusableTip;
-import org.fife.ui.rtextarea.RTextArea;
-import org.fife.ui.rtextarea.RTextAreaUI;
-import org.fife.ui.rtextarea.RUndoManager;
-import processing.app.*;
-
-import javax.swing.*;
-import javax.swing.event.EventListenerList;
-import javax.swing.event.HyperlinkEvent;
-import javax.swing.event.HyperlinkListener;
-import javax.swing.text.BadLocationException;
-import javax.swing.text.Document;
-import javax.swing.text.Segment;
-import javax.swing.undo.UndoManager;
-import java.awt.*;
+import java.awt.AWTKeyStroke;
+import java.awt.Color;
+import java.awt.Cursor;
+import java.awt.Font;
+import java.awt.Insets;
+import java.awt.KeyboardFocusManager;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.io.File;
@@ -57,10 +44,54 @@
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;
+import javax.swing.JPopupMenu;
+import javax.swing.KeyStroke;
+import javax.swing.event.EventListenerList;
+import javax.swing.event.HyperlinkEvent;
+import javax.swing.event.HyperlinkListener;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Document;
+import javax.swing.text.Segment;
+import javax.swing.undo.UndoManager;
+
+import org.apache.commons.compress.utils.IOUtils;
+import org.fife.ui.autocomplete.AutoCompletion;
+import org.fife.ui.autocomplete.AutoCompletionEvent;
+import org.fife.ui.autocomplete.AutoCompletionListener;
+import org.fife.ui.autocomplete.ParameterizedCompletion;
+import org.fife.ui.autocomplete.ParameterizedCompletionEvent;
+import org.fife.ui.rsyntaxtextarea.LinkGenerator;
+import org.fife.ui.rsyntaxtextarea.LinkGeneratorResult;
+import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
+import org.fife.ui.rsyntaxtextarea.Style;
+import org.fife.ui.rsyntaxtextarea.Theme;
+import org.fife.ui.rsyntaxtextarea.Token;
+import org.fife.ui.rsyntaxtextarea.TokenImpl;
+import org.fife.ui.rsyntaxtextarea.TokenTypes;
+import org.fife.ui.rsyntaxtextarea.focusabletip.FocusableTip;
+import org.fife.ui.rtextarea.RTextArea;
+import org.fife.ui.rtextarea.RTextAreaUI;
+import org.fife.ui.rtextarea.RUndoManager;
+
+import processing.app.Base;
+import processing.app.BaseNoGui;
+import processing.app.EditorListener;
+import processing.app.PreferencesData;
+import processing.app.packages.UserLibrary;
+import br.com.criativasoft.cpluslibparser.metadata.TAttribute;
+import br.com.criativasoft.cpluslibparser.metadata.TFunction;
+import cc.arduino.packages.autocomplete.CompletionsRenderer;
+import cc.arduino.packages.autocomplete.RealtimeCompletionsListener;
+import cc.arduino.packages.autocomplete.SketchCompletionProvider;
+import cc.arduino.packages.autocomplete.TDynamicLocation;
+import cc.arduino.packages.autocomplete.template.GenerateVarTemplate;
+import cc.arduino.packages.autocomplete.template.IncludeTemplate;
+
/**
* Arduino Sketch code editor based on RSyntaxTextArea (http://fifesoft.com/rsyntaxtextarea)
*
@@ -81,6 +112,8 @@ public class SketchTextArea extends RSyntaxTextArea {
private final PdeKeywords pdeKeywords;
+ private SketchCompletionProvider completionProvider;
+
public SketchTextArea(PdeKeywords pdeKeywords) throws IOException {
this.pdeKeywords = pdeKeywords;
installFeatures();
@@ -139,6 +172,73 @@ private void setSyntaxTheme(int tokenType, String id) {
getSyntaxScheme().setStyle(tokenType, style);
}
+
+ public void setupAutoComplete(SketchCompletionProvider provider) {
+
+ if(this.completionProvider != null){
+ completionProvider.uninstall();
+ }
+
+ this.completionProvider = provider;
+ AutoCompletion ac = new AutoCompletion(provider);
+
+
+ ac.setAutoActivationEnabled(true);
+ ac.setShowDescWindow(false);
+ ac.setListCellRenderer(new CompletionsRenderer());
+ ac.setParamChoicesRenderer(new CompletionsRenderer());
+ ac.setAutoCompleteSingleChoices(true);
+ ac.setParameterAssistanceEnabled(true);
+
+ ac.install(this);
+ provider.setAutoCompletion(ac);
+
+ ac.addAutoCompletionListener(new AutoCompletionListener() {
+ @Override
+ public void autoCompleteUpdate(AutoCompletionEvent e) {
+
+ if(e instanceof ParameterizedCompletionEvent){
+ ParameterizedCompletionEvent event = (ParameterizedCompletionEvent) e;
+
+ ParameterizedCompletion completion = event.getCompletion();
+
+ if(e.getEventType() == AutoCompletionEvent.Type.PARAMETER_COMPLETION_FINISH){
+ List parameterValues = event.getContext().getParameterValues();
+
+ // Force parser/load new Lib for autocomplete.
+ if(completion instanceof IncludeTemplate && !parameterValues.isEmpty()){
+ UserLibrary library = Base.getLibraries().getByName(parameterValues.get(0).replaceAll("(<|>|\\.h)", ""));
+ getCompletionProvider().getSketchData().addLibrary(library);
+ }
+
+ if(completion instanceof GenerateVarTemplate && !parameterValues.isEmpty()){
+ GenerateVarTemplate varTemplate = (GenerateVarTemplate) completion;
+ TAttribute var = new TAttribute(varTemplate.getType(), parameterValues.iterator().next());
+
+ // Insert new var in current function scope
+ TFunction functionScope = getCompletionProvider().getCurrentFunctionScope(SketchTextArea.this);
+ if(functionScope != null){
+ TDynamicLocation location = new TDynamicLocation(SketchTextArea.this.getDocument(), functionScope.getLocation());
+ var.setLocation(location);
+ functionScope.addLocalVariable(var);
+ }
+
+ }
+
+ }
+
+ if(e.getEventType() == AutoCompletionEvent.Type.PARAMETER_COMPLETION_SELECT){
+
+ }
+ }
+ }
+ });
+
+ }
+
+ public SketchCompletionProvider getCompletionProvider() {
+ return completionProvider;
+ }
// Removing the default focus traversal keys
// This is because the DefaultKeyboardFocusManager handles the keypress and consumes the event
diff --git a/app/src/processing/app/syntax/SyntaxErrorMarker.java b/app/src/processing/app/syntax/SyntaxErrorMarker.java
new file mode 100755
index 00000000000..a874bf100e9
--- /dev/null
+++ b/app/src/processing/app/syntax/SyntaxErrorMarker.java
@@ -0,0 +1,187 @@
+package processing.app.syntax;
+
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Element;
+
+import org.fife.ui.rsyntaxtextarea.RSyntaxDocument;
+import org.fife.ui.rsyntaxtextarea.RSyntaxUtilities;
+import org.fife.ui.rsyntaxtextarea.parser.*;
+import org.fife.ui.rtextarea.Gutter;
+import org.fife.ui.rtextarea.GutterIconInfo;
+
+import processing.app.Sketch;
+import processing.app.SketchCode;
+import br.com.criativasoft.cpluslibparser.LibraryIndex;
+import br.com.criativasoft.cpluslibparser.LibraryIndexListener;
+import br.com.criativasoft.cpluslibparser.metadata.TError;
+import br.com.criativasoft.cpluslibparser.metadata.TLibrary;
+import cc.arduino.packages.autocomplete.ArduinoLibraryScanner;
+import cc.arduino.packages.autocomplete.CompletionType;
+import cc.arduino.packages.autocomplete.CompletionsRenderer;
+import cc.arduino.packages.autocomplete.SketchCodeScanner;
+import cc.arduino.packages.autocomplete.SketchCompletionProvider;
+
+
+/**
+ * Shows the result of the errors found after running the parser ({@link LibraryIndex}, {@link SketchCodeScanner}).
+ * Only well ugly syntax errors will be caught (because of the nature of the analysis to be made).
+ * @author Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ */
+public class SyntaxErrorMarker extends AbstractParser implements LibraryIndexListener {
+
+ private TLibrary sketchLibrary;
+ private DefaultParseResult result;
+ private SketchTextArea textarea;
+ private SketchCode currentCode;
+
+ // TODO: this can be removed on fix: https://github.com/bobbylight/RSyntaxTextArea/issues/87
+ private Gutter gutter;
+ private List errorIcons = new ArrayList();
+
+ public SyntaxErrorMarker(SketchTextArea textarea) {
+ this.textarea = textarea;
+ this.gutter = RSyntaxUtilities.getGutter(textarea);
+ LibraryIndex.addListener(this);
+ result = new DefaultParseResult(this);
+ }
+
+ @Override
+ public ParseResult parse(RSyntaxDocument doc, String style) {
+
+ Element root = doc.getDefaultRootElement();
+ int lineCount = root.getElementCount();
+
+ if(sketchLibrary != null){
+ result.setParsedLines(0, lineCount-1);
+ }
+
+ return result;
+ }
+
+
+ @Override
+ public void onLoadLibrary(TLibrary library) {
+ if(library.name().startsWith(ArduinoLibraryScanner.SKETCH_LIB_PREFIX)){ // Sketch indexing finish
+ sketchLibrary = library;
+ collectErrors();
+ }
+ }
+
+
+ @Override
+ public void onUnloadLibrary(TLibrary library) {
+ if(library.name().startsWith(ArduinoLibraryScanner.SKETCH_LIB_PREFIX)){ // Sketch indexing finish
+ removeAll();
+ }
+ }
+
+ @Override
+ public void onReloadLibrary(TLibrary library) {
+ if(library.name().startsWith(ArduinoLibraryScanner.SKETCH_LIB_PREFIX)){ // Sketch indexing finish
+ sketchLibrary = library;
+ collectErrors();
+ }
+ }
+
+ private void collectErrors(){
+
+ if(sketchLibrary != null){
+
+ Set errors = sketchLibrary.getErrors();
+
+ result.clearNotices();
+
+ for (GutterIconInfo gutterIconInfo : errorIcons) {
+ gutter.removeTrackingIcon(gutterIconInfo);
+ }
+
+ if(!errors.isEmpty()){
+ for (TError error : errors) {
+ addError(error);
+ }
+ }
+ textarea.forceReparsing(this);
+ }
+
+ }
+
+ public void addError(TError error){
+ ErrorParserNotice notice = new ErrorParserNotice(this, error);
+ result.addNotice(notice);
+ // TODO: This(gutter) can be removed on fix: RSyntaxTextArea/issues/87
+ if(gutter != null){
+ try {
+ GutterIconInfo errorIcon = gutter.addOffsetTrackingIcon(error.getStartOffset(), CompletionsRenderer.getIcon(CompletionType.ERROR), error.name());
+ errorIcons.add(errorIcon);
+ } catch (BadLocationException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public static class ErrorParserNotice extends DefaultParserNotice{
+
+ private TError error;
+ private SyntaxErrorMarker parser;
+
+ public ErrorParserNotice(SyntaxErrorMarker parser, TError error) {
+ super(parser, error.getName(), -1, error.getStartOffset() , error.getLength());
+ this.error = error;
+ this.parser = parser;
+ setColor(Color.RED);
+ setShowInEditor(true);
+ }
+
+ public TError getError() {
+ return error;
+ }
+
+ @Override
+ public String getToolTipText() {
+ return error.getName();
+ }
+
+ @Override
+ public boolean getShowInEditor() {
+
+ if(parser.getCurrentCode() != null){
+
+ String path = parser.getCurrentCode().getFile().getPath();
+
+ if(error.getPath() != null){
+ return error.getPath().equals(path);
+ }else{
+ return super.getShowInEditor();
+ }
+
+ }else{
+ return super.getShowInEditor();
+ }
+
+ }
+
+ }
+
+ public void removeAll() {
+ result.clearNotices();
+ textarea.forceReparsing(this);
+ for (GutterIconInfo gutterIconInfo : errorIcons) {
+ gutter.removeTrackingIcon(gutterIconInfo);
+ }
+ }
+
+ public void setCurrentCode(SketchCode currentCode) {
+ this.currentCode = currentCode;
+ textarea.forceReparsing(this);
+ }
+
+ public SketchCode getCurrentCode() {
+ return currentCode;
+ }
+
+}
diff --git a/app/src/processing/app/syntax/TokenErrorMarker.java b/app/src/processing/app/syntax/TokenErrorMarker.java
new file mode 100755
index 00000000000..914240bd426
--- /dev/null
+++ b/app/src/processing/app/syntax/TokenErrorMarker.java
@@ -0,0 +1,91 @@
+package processing.app.syntax;
+
+import java.awt.Color;
+
+import javax.swing.text.Element;
+
+import org.fife.ui.rsyntaxtextarea.RSyntaxDocument;
+import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
+import org.fife.ui.rsyntaxtextarea.Token;
+import org.fife.ui.rsyntaxtextarea.TokenMaker;
+import org.fife.ui.rsyntaxtextarea.modes.CPlusPlusTokenMaker;
+import org.fife.ui.rsyntaxtextarea.parser.AbstractParser;
+import org.fife.ui.rsyntaxtextarea.parser.DefaultParseResult;
+import org.fife.ui.rsyntaxtextarea.parser.DefaultParserNotice;
+import org.fife.ui.rsyntaxtextarea.parser.ParseResult;
+import org.fife.ui.rsyntaxtextarea.parser.ParserNotice;
+
+/**
+ * Displays Syntax errors at the level of tokens, these errors are generated by {@link TokenMaker} like {@link CPlusPlusTokenMaker}
+ * TODO: Currently he is the parser of the entire document, I am waiting for the resolution of the bug below. (maybe this class is to removed)
+ * https://github.com/bobbylight/RSyntaxTextArea/issues/86
+ * @author Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ */
+public class TokenErrorMarker extends AbstractParser {
+
+ private RSyntaxTextArea textarea;
+ private DefaultParseResult result;
+
+ public TokenErrorMarker(RSyntaxTextArea textarea) {
+ setEnabled(true);
+ this.textarea = textarea;
+ result = new DefaultParseResult(this);
+ }
+
+ @Override
+ public ParseResult parse(RSyntaxDocument doc, String style) {
+
+ Element root = doc.getDefaultRootElement();
+ int lineCount = root.getElementCount();
+
+ result.clearNotices();
+ result.setParsedLines(0, lineCount-1);
+
+ for (int line=0; line 0 && end == -1) end = t.getOffset();
+ }
+ t = t.getNextToken();
+ }
+
+ if (start>-1) {
+ DefaultParserNotice pn = new DefaultParserNotice(this, "syntax error", line, start, (end-start));
+ pn.setLevel(ParserNotice.Level.ERROR);
+ pn.setColor(Color.RED);
+ result.addNotice(pn);
+ found = true;
+ }
+
+ return found;
+ }
+
+ private boolean isError(Token token){
+
+ switch (token.getType()) {
+ case Token.ERROR_CHAR:
+ case Token.ERROR_IDENTIFIER:
+ case Token.ERROR_NUMBER_FORMAT:
+ case Token.ERROR_STRING_DOUBLE:
+ return true;
+ }
+
+ return false;
+ }
+
+}
diff --git a/arduino-autocomplete/.classpath b/arduino-autocomplete/.classpath
new file mode 100755
index 00000000000..b8f3695e6f6
--- /dev/null
+++ b/arduino-autocomplete/.classpath
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/arduino-autocomplete/.gitignore b/arduino-autocomplete/.gitignore
new file mode 100755
index 00000000000..583ba9546e9
--- /dev/null
+++ b/arduino-autocomplete/.gitignore
@@ -0,0 +1,2 @@
+/bin/
+arduino-autocomplete.jar
\ No newline at end of file
diff --git a/arduino-autocomplete/.project b/arduino-autocomplete/.project
new file mode 100755
index 00000000000..16edc16e828
--- /dev/null
+++ b/arduino-autocomplete/.project
@@ -0,0 +1,17 @@
+
+
+ arduino-autocomplete
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/arduino-autocomplete/build.xml b/arduino-autocomplete/build.xml
new file mode 100755
index 00000000000..700d73254f4
--- /dev/null
+++ b/arduino-autocomplete/build.xml
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/arduino-autocomplete/src/cc/arduino/packages/autocomplete/ArduinoLibraryScanner.java b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/ArduinoLibraryScanner.java
new file mode 100755
index 00000000000..76d24041da4
--- /dev/null
+++ b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/ArduinoLibraryScanner.java
@@ -0,0 +1,89 @@
+/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
+
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ * Copyright 2015 Arduino LLC
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
+package cc.arduino.packages.autocomplete;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import processing.app.helpers.filefilters.OnlyFilesWithExtension;
+import processing.app.packages.UserLibrary;
+import br.com.criativasoft.cpluslibparser.LibraryScanner;
+import br.com.criativasoft.cpluslibparser.SourceParser;
+
+/**
+ * Scanner for Arduino libraries.
+ * This class is only a bridge between the libraries and the {@link SourceParser}, making the settings and adjustments
+ * @author Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ * @date 20/11/2014
+ */
+public class ArduinoLibraryScanner extends LibraryScanner {
+
+ public static final String SKETCH_LIB_PREFIX = "private:sketch:"; // for autocomplete metadata
+
+ private UserLibrary library;
+
+ private static final List ignoredFiles = new ArrayList();
+
+ static{
+ ignoredFiles.add("USBCore.h");
+ ignoredFiles.add("USBDesc.h");
+ }
+
+ public ArduinoLibraryScanner(UserLibrary library) {
+ this.library = library;
+ }
+
+ @Override
+ protected File[] getFilesToParse(File folder) {
+
+ // check /src directory
+ File src = new File(folder, "src");
+ if(src.exists()){
+ folder = src;
+ }
+
+ return folder.listFiles(new OnlyFilesWithExtension(ignoredFiles, ".h"));
+ }
+
+ @Override
+ protected void configParser(SourceParser parser, File currentFile) {
+ parser.addMacro("UBRR0H", "1"); // Enable Serial !
+ }
+
+ @Override
+ protected String getLibraryName() {
+ return library.getName();
+ }
+
+}
diff --git a/arduino-autocomplete/src/cc/arduino/packages/autocomplete/CompletionProviderWithContext.java b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/CompletionProviderWithContext.java
new file mode 100755
index 00000000000..dbf314dd082
--- /dev/null
+++ b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/CompletionProviderWithContext.java
@@ -0,0 +1,376 @@
+/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
+
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ * Copyright 2015 Arduino LLC
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+package cc.arduino.packages.autocomplete;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.logging.Logger;
+
+import javax.swing.text.JTextComponent;
+
+import org.fife.ui.autocomplete.Completion;
+import org.fife.ui.autocomplete.DefaultCompletionProvider;
+import org.fife.ui.autocomplete.FunctionCompletion;
+import org.fife.ui.autocomplete.Util;
+import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
+
+import processing.app.helpers.Predicate;
+import br.com.criativasoft.cpluslibparser.LibraryIndex;
+import br.com.criativasoft.cpluslibparser.metadata.TAttribute;
+import br.com.criativasoft.cpluslibparser.metadata.TClass;
+import br.com.criativasoft.cpluslibparser.metadata.TClass.TClassType;
+import br.com.criativasoft.cpluslibparser.metadata.TElement;
+import br.com.criativasoft.cpluslibparser.metadata.TElementLocation;
+import br.com.criativasoft.cpluslibparser.metadata.TFunction;
+import br.com.criativasoft.cpluslibparser.metadata.TLibrary;
+
+/**
+ * Autocomplete logic implementation for instance functions, static functions and local variables.
+ * It determines the options that will be presented in accordance with the current context.
+ * @author Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ */
+public class CompletionProviderWithContext extends DefaultCompletionProvider{
+
+ private final static Logger LOG = Logger.getLogger(CompletionProviderWithContext.class.getName());
+
+ private static final String DOT = ".";
+ private static final String POINTER = "->";
+ private static final String STATIC = "::";
+ private TLibrary sketchLibrary; // classes, variables, functions of sketch
+
+ private List sketchCompletions = new ArrayList(); // variables and functions of sketch
+
+ public CompletionProviderWithContext() {
+ super();
+ }
+
+ public void setSketchLibrary(TLibrary sketchLibrary) {
+ this.sketchLibrary = sketchLibrary;
+ }
+
+ @Override
+ public List getCompletionsImpl(JTextComponent comp) {
+
+ RSyntaxTextArea textarea = (RSyntaxTextArea) comp;
+
+ String entredText = getAlreadyEnteredText(comp);
+
+ List contextCompletions = null;
+
+ LOG.finest("entredText = "+ entredText);
+
+ // Functions/Attrs of Classes
+ if (entredText != null && entredText.length() > 0) {
+
+ String separator = null;
+
+ if (entredText.contains(DOT)) separator = DOT;
+ if (entredText.contains(POINTER))separator = POINTER;
+ if (entredText.contains(STATIC)) separator = STATIC;
+
+ if (separator != null) {
+ String var = entredText.substring(0, entredText.lastIndexOf(separator));
+ String startMethod = entredText.substring(entredText.lastIndexOf(separator) + separator.length());
+ contextCompletions = getCompletionsForClass(var, separator, startMethod, textarea);
+ }
+
+ }
+
+ // Only show functions/attrs of class.
+ if (contextCompletions != null) return contextCompletions;
+
+ List list = new LinkedList();
+
+ TFunction functionScope = getCurrentFunctionScope(textarea);
+
+ if (functionScope != null && sketchCompletions != null && !sketchCompletions.isEmpty()) {
+
+ // Variables and functions
+ list.addAll(sketchCompletions);
+
+ // Local variables of functions.
+ list.addAll(getVariablesInCurrentScope(textarea));
+
+ // Need to order before searching
+ if(list.size() != sketchCompletions.size()){
+ Collections.sort(list, comparator);
+ }
+
+ List filterCompletions = filterCompletions(entredText, list);
+
+ if (filterCompletions != null) list = filterCompletions;
+
+ }
+
+ List completions = super.getCompletionsImpl(comp);
+
+ // Outside of function (only show classes)
+ if (functionScope == null) {
+ for (Completion completion : completions) {
+ if (!(completion instanceof FunctionCompletion)) {
+ list.add(completion);
+ }
+ }
+ } else {
+ list.addAll(completions);
+ }
+
+ return list;
+
+ }
+
+ public List getVariablesInCurrentScope(RSyntaxTextArea textarea){
+
+ int caretPos = textarea.getCaretPosition();
+ TFunction functionScope = getCurrentFunctionScope(textarea);
+ List completions = new ArrayList();
+
+ if(functionScope != null){
+
+ Set localVariables = functionScope.getLocalVariables();
+
+ if(localVariables != null){
+ for (TAttribute var : localVariables) {
+ if(var.getLocation().getStartOffset() <= caretPos){ // try to filter variables not declared at cursor position
+ // TODO: this may not work if many rows were changed after the last parser
+ completions.add(new TElementCompletion(this, var));
+ }
+ }
+ }
+
+ }
+
+
+ return completions;
+
+ }
+
+ public List getCompletionsForClass(String context, String token, String startMethod, RSyntaxTextArea textarea){
+
+ List list = new LinkedList();
+
+ boolean isInstance = (token == POINTER || Character.isLowerCase(context.charAt(0)));
+ boolean isStatic = (token == STATIC && Character.isUpperCase(context.charAt(0)));
+
+ TClass tClass = null;
+
+ if(!isStatic){
+ // Find the correct type based on global/local variables
+ Set variables = new HashSet();
+ variables.addAll(sketchLibrary.getGlobalVariables());
+
+ TFunction functionScope = getCurrentFunctionScope(textarea);
+
+ if(functionScope != null){
+ variables.addAll(functionScope.getLocalVariables());
+ }
+
+ for (TAttribute attribute : variables) {
+ if(attribute.name().equals(context)){
+ tClass = LibraryIndex.getClass(attribute.getType());
+ isInstance = true;
+ break;
+ }
+ }
+ }
+
+ if(tClass == null){
+ tClass = LibraryIndex.getClass(context); // if isInstance, ignore case !!
+ }
+
+ if(tClass == null){
+
+ TLibrary library = LibraryIndex.getLibrary(context);
+ if(library != null){
+ TElement variable = library.findMember(context);
+ if(variable instanceof TAttribute){
+ tClass = LibraryIndex.getClass(((TAttribute) variable).getType());
+ if(tClass != null) isInstance = true;
+ }
+
+ }
+
+ }
+
+
+ if(tClass != null){
+
+ Collection functions = tClass.getFunctions(true);
+ Collection attributes = tClass.getAttributes();
+
+ // if the user had entered part of the function/attr name
+ if(startMethod != null && startMethod.length() > 0){
+ int matchMode = (startMethod.length() > 2 ? TElementFilter.MATCH_CONTAINS : TElementFilter.MATCH_START);
+ functions = Predicate.filter(functions, new TFunctionFilter(startMethod, matchMode));
+ attributes = Predicate.filter(attributes, new TAttributeFilter(startMethod, matchMode));
+ }
+
+ String startTemplate = context + token;
+
+ for (TFunction tFunction : functions) {
+
+ if(!tFunction.isPublic() || tFunction.isConstructor()) continue;
+
+ boolean add = false;
+
+ // Instance
+ if(isInstance && !tFunction.isStatic()){
+ add = true;
+ }
+
+ // Static
+ if(!isInstance && tFunction.isStatic()){
+ add = true;
+ }
+
+ // Extern (show static and instance)
+ if(tClass.getType() == TClassType.EXTERN){
+ add = true;
+ }
+
+ if(add){
+ list.add(new TFunctionCompletion(this, tFunction, startTemplate));
+ }
+
+ }
+
+ for (TAttribute attr : attributes) {
+
+ // Instance
+ if(isInstance && !attr.isStatic()){
+ list.add(new TElementCompletion(this, attr , startTemplate));
+ }
+
+ // Static
+ if(!isInstance && attr.isStatic() || tClass.getType() == TClassType.EXTERN){
+ list.add(new TElementCompletion(this, attr , startTemplate));
+ }
+
+ }
+
+ }
+
+ return list;
+ }
+
+ public void setSketchCompletions(List sketchCompletions) {
+ this.sketchCompletions = sketchCompletions;
+ Collections.sort(sketchCompletions, comparator);
+ }
+
+ public List getSketchCompletions() {
+ return sketchCompletions;
+ }
+
+
+ /**
+ * Find function at the caret position
+ * @param textarea
+ * @return
+ */
+ public TFunction getCurrentFunctionScope(RSyntaxTextArea textarea){
+
+ int caretPos = textarea.getCaretPosition();
+
+ Set globalFunctions = sketchLibrary.getGlobalFunctions();
+
+ for (TFunction tFunction : globalFunctions) {
+ TElementLocation location = tFunction.getLocation();
+ if(location != null && location.containsOffset(caretPos)){
+
+ LOG.finest("function = " + tFunction + ", loc: " + location.toString());
+
+ return tFunction;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Filter through the options that can be applied to the text that the user entered
+ * @param alreadyEnteredText
+ * @param completions - Must be ordered before searching
+ * @return
+ */
+ protected List filterCompletions(String alreadyEnteredText, List completions) {
+
+ if(alreadyEnteredText == null || alreadyEnteredText.isEmpty()) return new ArrayList(completions);
+ List retVal = new ArrayList();
+
+ if (alreadyEnteredText!=null) {
+
+ int index = Collections.binarySearch(completions, alreadyEnteredText, comparator);
+ if (index<0) { // No exact match
+ index = -index - 1;
+ }
+ else {
+ // If there are several overloads for the function being
+ // completed, Collections.binarySearch() will return the index
+ // of one of those overloads, but we must return all of them,
+ // so search backward until we find the first one.
+ int pos = index - 1;
+ while (pos>0 &&
+ comparator.compare(completions.get(pos), alreadyEnteredText)==0) {
+ retVal.add(completions.get(pos));
+ pos--;
+ }
+ }
+
+ while (index' == ch || '-' == ch || '<' == ch || '#' == ch || ':' == ch /**|| getParameterListStart() == ch */;
+ }
+
+}
diff --git a/arduino-autocomplete/src/cc/arduino/packages/autocomplete/CompletionType.java b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/CompletionType.java
new file mode 100755
index 00000000000..58ee48653df
--- /dev/null
+++ b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/CompletionType.java
@@ -0,0 +1,46 @@
+/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
+
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ * Copyright 2015 Arduino LLC
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+package cc.arduino.packages.autocomplete;
+
+public enum CompletionType {
+ LIBRARY,
+ CLASS,
+ ENUM,
+ STRUCT,
+ LOCAL_VAR,
+ STATIC_VAR,
+ VARIABLE,
+ FUNCTION,
+ TEMPLATE,
+ ERROR
+
+}
diff --git a/arduino-autocomplete/src/cc/arduino/packages/autocomplete/CompletionsRenderer.java b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/CompletionsRenderer.java
new file mode 100755
index 00000000000..a6853ca02ec
--- /dev/null
+++ b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/CompletionsRenderer.java
@@ -0,0 +1,166 @@
+/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
+
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ * Copyright 2015 Arduino LLC
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+package cc.arduino.packages.autocomplete;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Font;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.swing.DefaultListCellRenderer;
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.swing.JList;
+
+import org.fife.ui.autocomplete.BasicCompletion;
+import org.fife.ui.autocomplete.FunctionCompletion;
+import org.fife.ui.autocomplete.ShorthandCompletion;
+import org.fife.ui.autocomplete.TemplateCompletion;
+import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
+
+import br.com.criativasoft.cpluslibparser.metadata.TElement;
+import br.com.criativasoft.cpluslibparser.metadata.TFunction;
+
+/**
+ * Class responsible for formatting the elements of the autocomplete list
+ * @author Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ * @date 11/12/2014
+ */
+public class CompletionsRenderer extends DefaultListCellRenderer {
+
+ private static final long serialVersionUID = 1L;
+
+ private static final Color HIGHLIGHT_COLOR = new Color(74, 144, 217);
+
+ private static final String GRAY = "#A0A0A0";
+ private static final String LIGHT_BLUE = "#008080";
+
+ /** Keeps the HTML descriptions from "wrapping" in the list, which cuts off words. */
+ private static final String PREFIX = "";
+
+ private static Map iconsTypes = new HashMap();
+
+ static{
+ iconsTypes.put(CompletionType.CLASS, getIcon("class.gif"));
+ iconsTypes.put(CompletionType.ENUM, getIcon("enum.gif"));
+ iconsTypes.put(CompletionType.VARIABLE, getIcon("variable.gif"));
+ iconsTypes.put(CompletionType.LOCAL_VAR, getIcon("variable_local.gif"));
+ iconsTypes.put(CompletionType.STATIC_VAR, getIcon("variable_static.gif"));
+ iconsTypes.put(CompletionType.FUNCTION, getIcon("function.gif"));
+ iconsTypes.put(CompletionType.ERROR, getIcon("error.gif"));
+ iconsTypes.put(CompletionType.TEMPLATE, getIcon("template_obj.gif"));
+ }
+
+
+ private static Icon getIcon(String image){
+ return new ImageIcon(CompletionsRenderer.class.getResource("icons/"+image));
+ }
+
+ public static Icon getIcon(CompletionType tokenType){
+ return iconsTypes.get(tokenType);
+ }
+
+ public CompletionsRenderer() {
+ setOpaque(true);
+ // Font f = Theme.getDefaultFont();
+ Font f = RSyntaxTextArea.getDefaultFont();
+ setFont(f.deriveFont(f.getStyle() & ~Font.BOLD)); // remove bold.
+ }
+
+ @Override
+ public Component getListCellRendererComponent(JList list, Object value,
+ int index, boolean isSelected,
+ boolean cellHasFocus) {
+
+ String text = null;
+ CompletionType tokenType = null;
+
+ if(value instanceof TElementCompletion){
+
+ TElementCompletion completion = (TElementCompletion) value;
+ TElement element = completion.getElement();
+ tokenType = completion.getType();
+ text = element.getHtmlRepresentation();
+
+ }else if(value instanceof TFunctionCompletion){
+
+ TFunctionCompletion completion = (TFunctionCompletion) value;
+ TFunction function = completion.getFunction();
+ text = function.getHtmlRepresentation();
+ tokenType = CompletionType.FUNCTION;
+
+ }else if(value instanceof ShorthandCompletion){
+ text = ((ShorthandCompletion) value).getShortDescription();
+ tokenType = CompletionType.TEMPLATE;
+ }else if(value instanceof FunctionCompletion){
+ text = ((FunctionCompletion) value).getShortDescription();
+ tokenType = CompletionType.FUNCTION;
+ }else if(value instanceof BasicCompletion){
+ text = ((BasicCompletion) value).getInputText();
+ if( ((BasicCompletion) value).getShortDescription() != null){
+ text = ((BasicCompletion) value).getShortDescription();
+ }
+ }else if(value instanceof TemplateCompletion){
+ TemplateCompletion template = (TemplateCompletion) value;
+ text = font(template.getInputText(), LIGHT_BLUE) + font(" - " + template.getDefinitionString(), GRAY) ;
+ }
+
+ if(text == null){
+ text = value.toString();
+ }
+
+ // Find Icon
+ if(tokenType != null){
+ setIcon(iconsTypes.get(tokenType));
+ }else{
+ setIcon(iconsTypes.get(CompletionType.TEMPLATE));
+ }
+
+ if (isSelected) {
+ setText(text.replaceAll("\\<[^>]*>",""));
+ setBackground(HIGHLIGHT_COLOR);
+ setForeground(Color.white);
+ } else {
+ setText(PREFIX + text);
+ setBackground(Color.white);
+ setForeground(Color.black);
+ }
+
+ return this;
+ }
+
+ private String font(String text, String color){
+ return ""+text+"";
+ }
+
+}
diff --git a/arduino-autocomplete/src/cc/arduino/packages/autocomplete/ParameterChoicesProvider.java b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/ParameterChoicesProvider.java
new file mode 100755
index 00000000000..b839286f6d2
--- /dev/null
+++ b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/ParameterChoicesProvider.java
@@ -0,0 +1,163 @@
+/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
+
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ * Copyright 2015 Arduino LLC
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+package cc.arduino.packages.autocomplete;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.swing.text.JTextComponent;
+
+import org.fife.ui.autocomplete.BasicCompletion;
+import org.fife.ui.autocomplete.Completion;
+import org.fife.ui.autocomplete.CompletionProvider;
+import org.fife.ui.autocomplete.CompletionProviderBase;
+import org.fife.ui.autocomplete.ParameterizedCompletion;
+import org.fife.ui.autocomplete.ParameterizedCompletion.Parameter;
+
+import cc.arduino.packages.autocomplete.TFunctionCompletion.TFunctionParam;
+import br.com.criativasoft.cpluslibparser.metadata.TFunction;
+import br.com.criativasoft.cpluslibparser.metadata.TParam;
+
+/**
+ * This is used when a user code-completes a parameterized completion, such as a function or method.
+ * For any parameter to the function/method, this object can return possible completions.
+ * @see {@link CompletionProviderBase#setParameterChoicesProvider(org.fife.ui.autocomplete.ParameterChoicesProvider)}
+ * @author Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ * @date 09/12/2014
+ */
+public class ParameterChoicesProvider implements org.fife.ui.autocomplete.ParameterChoicesProvider {
+
+ private SketchCompletionProvider provider;
+
+ public ParameterChoicesProvider(SketchCompletionProvider provider) {
+ super();
+ this.provider = provider;
+ }
+
+ @Override
+ public List getParameterChoices(JTextComponent tc, ParameterizedCompletion pc, Parameter param) {
+
+ if (param instanceof TFunctionParam) {
+
+ TFunctionParam functionParam = (TFunctionParam) param;
+ TFunction function = functionParam.getFunction();
+ TParam tParam = functionParam.getAttributeParam();
+
+ // FIXME: REMOVE AFTER IMPLEMENT PARSER FROM SOURCE
+ if (function.name().equals("begin") && tParam.name().equals("baud")) {
+ // @param baud (Values: 300, 600, 1200 ...)
+ tParam.setAllowedValues("300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 115200");
+ }
+
+ if (function.name().equals("pinMode") && tParam.name().equals("mode")) {
+ tParam.setAllowedValues("OUTPUT, INPUT, INPUT_PULLUP");
+ }
+
+ if (function.name().equals("digitalWrite") && tParam.name().equals("value")) {
+ tParam.setAllowedValues("HIGH, LOW");
+ }
+
+ // end: remove --------------
+
+ if (tParam.getAllowedValues() != null) {
+ return createFromAllowedValues(tParam);
+ }
+
+ }
+
+ if(pc instanceof TemplateChoicesCompletion){
+ TemplateChoicesCompletion choicesCompletion = (TemplateChoicesCompletion) pc;
+ return choicesCompletion.getChoices(param);
+ }
+
+ return null;
+ }
+
+ private List createFromAllowedValues(TParam param) {
+
+ List completions = new LinkedList();
+
+ String allowedValues = param.getAllowedValues();
+
+ String[] strings = allowedValues.split(",");
+
+ for (String key : strings) {
+ completions.add(new ParamCompletion(provider, key.trim(), param.getType()));
+ }
+
+ return completions;
+ }
+
+
+ // it is only necessary to properly sort integer values.
+ private static class ParamCompletion extends BasicCompletion {
+
+ private Long value;
+
+ public ParamCompletion(CompletionProvider provider, String replacementText,
+ String type) {
+ super(provider, replacementText);
+
+ if (isNumber(type)) {
+ try {
+ value = Long.parseLong(replacementText);
+ } catch (Exception e) {}
+ }
+
+ }
+
+ private boolean isNumber(String type) {
+ if (type.contains("int") || type.contains("long")) {
+ return true;
+ }
+
+ return false;
+ }
+
+ public Long getValue() {
+ return value;
+ }
+
+ @Override
+ public int compareTo(Completion c2) {
+
+ if(value != null){
+ return value.compareTo(((ParamCompletion)c2).getValue());
+ }else{
+ return super.compareTo(c2);
+ }
+
+ }
+
+ }
+
+}
diff --git a/arduino-autocomplete/src/cc/arduino/packages/autocomplete/RealtimeCompletionsListener.java b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/RealtimeCompletionsListener.java
new file mode 100755
index 00000000000..efe7f5344d1
--- /dev/null
+++ b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/RealtimeCompletionsListener.java
@@ -0,0 +1,205 @@
+/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
+
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ * Copyright 2015 Arduino LLC
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+package cc.arduino.packages.autocomplete;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.util.Set;
+import java.util.logging.Logger;
+
+import javax.swing.Timer;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Document;
+import javax.swing.text.Element;
+import javax.swing.text.Segment;
+
+import processing.app.SketchCode;
+import processing.app.SketchData;
+import br.com.criativasoft.cpluslibparser.LibraryIndex;
+import br.com.criativasoft.cpluslibparser.metadata.TElement;
+import br.com.criativasoft.cpluslibparser.metadata.TError;
+import br.com.criativasoft.cpluslibparser.metadata.TFunction;
+import br.com.criativasoft.cpluslibparser.metadata.TLibrary;
+
+/**
+ * This is the class responsible for monitoring the events and changes in the code and decide when it should
+ * be done a parser to extract the metadata to make the autocomplete
+ * This listener is registered by: {@link SketchCompletionProvider#onSketchInserted(Sketch, SketchCode)} and {@link PdeTextArea}.
+ * @author Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ * @date 22/11/2014
+ */
+public class RealtimeCompletionsListener implements KeyListener, DocumentListener {
+
+ private final static Logger LOG = Logger.getLogger(RealtimeCompletionsListener.class.getName());
+
+ private SketchData sketchData;
+ private Segment segment = new Segment();
+ private Timer debounce;
+ private int startOffs;
+ private int endOffs;
+ private int startLine;
+ private int endLine;
+
+ public RealtimeCompletionsListener(SketchData sketchData) {
+ this.sketchData = sketchData;
+ debounce = new Timer(800, new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ analizeModified();
+ }
+ });
+ debounce.setRepeats(false);
+
+ }
+
+ @Override
+ public void keyTyped(KeyEvent e) {
+
+ }
+
+ @Override
+ public void keyPressed(KeyEvent e) {
+
+ }
+
+ @Override
+ public void keyReleased(KeyEvent e) {
+ if(e.getKeyChar() == ';' || e.getKeyChar() == '}'){
+ fireParser();
+ }
+ }
+
+
+ protected void fireParser(){
+ SketchCode sketchCode = sketchData.getCurrentCode();
+ TLibrary library = sketchData.getSketchMetadata();
+ if(library != null){
+
+ long time = System.currentTimeMillis();
+ if(library.getLastUpdate() > 0 && (time - library.getLastUpdate() < 2000 )){
+ LOG.fine("Ignoring parser, a recent parser has been done !");
+ return;
+ }
+
+ library.clear(sketchCode.getFile().getPath());
+ }
+
+ try {
+ Document document = SketchCompletionProvider.getDocument(sketchCode);
+ String code = document.getText(0, document.getLength());
+ LibraryIndex.scanSource(code, new SketchCodeScanner(sketchData, sketchData.getCurrentCode())); // fire #onLoadLibrary on finish
+ } catch (BadLocationException e) {
+ LOG.severe(e.getMessage());
+ }
+ }
+
+ @Override
+ public void insertUpdate(DocumentEvent e) {
+ startOffs = e.getOffset();
+ endOffs = startOffs + e.getLength();
+ Document doc = e.getDocument();
+ Element root = doc.getDefaultRootElement();
+ startLine = root.getElementIndex(startOffs);
+ endLine = root.getElementIndex(endOffs);
+
+ debounce.restart(); // waits for the user stops typing
+
+ try {
+ doc.getText(startOffs, e.getLength(), segment);
+
+ if (startLine != endLine) { // Inserted text covering > 1 line...
+ // fireParser();
+ // System.out.println("RealtimeCompletionsListener.insertUpdate: startLine != endLine");
+
+ } else if (segment.length() > 0&& segment.charAt(segment.length() - 1) == '}') {
+ // System.out.println("RealtimeCompletionsListener.insertUpdate: == '}'");
+ }
+ } catch (BadLocationException e2) {
+ e2.printStackTrace();
+ }
+
+ }
+
+ @Override
+ public void removeUpdate(DocumentEvent e) {
+
+ debounce.restart(); // waits for the user stops typing
+
+ }
+
+ @Override
+ public void changedUpdate(DocumentEvent e) {
+
+ }
+
+ protected void analizeModified(){
+
+
+ if(sketchData != null && sketchData.getSketchMetadata() != null){
+ TLibrary metadata = sketchData.getSketchMetadata();
+
+ // Check errors
+ if(TError.containsError(startOffs, metadata.getErrors())){
+ LOG.fine("Offset contains erros, firing parser");
+ fireParser();
+ return;
+ }
+
+ // Variables
+ if(TElement.contains(startOffs, metadata.getGlobalVariables())){
+ LOG.fine("Changing a global variable, firing parser");
+ fireParser();
+ return;
+ }
+
+ Set functions = metadata.getGlobalFunctions();
+
+ for (TFunction function : functions) {
+ if(!"setup".equals(function.name())){
+ if(TElement.contains(startOffs, function.getLocalVariables())){
+ LOG.fine("Changing a local variable, firing parser");
+ fireParser();
+ return;
+ }
+ }
+ }
+
+ }
+
+ }
+
+
+}
diff --git a/arduino-autocomplete/src/cc/arduino/packages/autocomplete/SketchCodeScanner.java b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/SketchCodeScanner.java
new file mode 100755
index 00000000000..7064288c6f5
--- /dev/null
+++ b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/SketchCodeScanner.java
@@ -0,0 +1,85 @@
+/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
+
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ * Copyright 2015 Arduino LLC
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+package cc.arduino.packages.autocomplete;
+
+import java.io.File;
+
+import processing.app.SketchCode;
+import processing.app.SketchData;
+import processing.app.helpers.filefilters.OnlyFilesWithExtension;
+import br.com.criativasoft.cpluslibparser.LibraryScanner;
+import br.com.criativasoft.cpluslibparser.SourceParser;
+
+public class SketchCodeScanner extends LibraryScanner {
+
+ private SketchCode code;
+ private SketchData sketch;
+
+ public SketchCodeScanner(SketchData sketchData, SketchCode code) {
+ this(sketchData);
+ this.code = code;
+ }
+
+ public SketchCodeScanner(SketchData sketch) {
+ super();
+ this.sketch = sketch;
+ setSerialize(false); // not cache
+ setDeserialize(false); // not cache
+ }
+
+ @Override
+ protected File[] getFilesToParse(File folder) {
+
+ if(code != null){ // single file{
+
+ return new File[]{code.getFile()};
+
+ }else{
+
+ return folder.listFiles(new OnlyFilesWithExtension("ino", "pde", "c", "cpp", "h"));
+
+ }
+
+ }
+
+ @Override
+ protected void configParser(SourceParser parser, File currentFile) {
+ parser.setParseInternalAttrs(true);
+ if(currentFile == null) parser.setDefaultFileName(code.getFileName());
+ }
+
+ @Override
+ protected String getLibraryName() {
+ return SketchCompletionProvider.SKETCH_LIB_PREFIX + sketch.getName();
+ }
+
+}
diff --git a/arduino-autocomplete/src/cc/arduino/packages/autocomplete/SketchCompletionProvider.java b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/SketchCompletionProvider.java
new file mode 100755
index 00000000000..9b922d0266a
--- /dev/null
+++ b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/SketchCompletionProvider.java
@@ -0,0 +1,563 @@
+/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
+
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ * Copyright 2015 Arduino LLC
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+package cc.arduino.packages.autocomplete;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.swing.text.Document;
+
+import org.fife.ui.autocomplete.AutoCompletion;
+import org.fife.ui.autocomplete.Completion;
+import org.fife.ui.autocomplete.LanguageAwareCompletionProvider;
+import org.fife.ui.autocomplete.TemplateCompletion;
+import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
+
+import processing.app.BaseNoGui;
+import processing.app.PreferencesData;
+import processing.app.SketchCode;
+import processing.app.SketchData;
+import processing.app.SketchDocumentProvider;
+import processing.app.debug.TargetPlatform;
+import processing.app.helpers.StringUtils;
+import processing.app.packages.LibraryList;
+import processing.app.packages.LibraryListener;
+import processing.app.packages.SketchListener;
+import processing.app.packages.UserLibrary;
+import br.com.criativasoft.cpluslibparser.LibraryIndex;
+import br.com.criativasoft.cpluslibparser.LibraryIndexListener;
+import br.com.criativasoft.cpluslibparser.metadata.TAttribute;
+import br.com.criativasoft.cpluslibparser.metadata.TClass;
+import br.com.criativasoft.cpluslibparser.metadata.TElement;
+import br.com.criativasoft.cpluslibparser.metadata.TElementLocation;
+import br.com.criativasoft.cpluslibparser.metadata.TFunction;
+import br.com.criativasoft.cpluslibparser.metadata.TLibrary;
+import cc.arduino.packages.autocomplete.template.GenerateVarTemplate;
+import cc.arduino.packages.autocomplete.template.IncludeTemplate;
+
+/**
+ * CompletionProvider for Arduino/CPP Language.
+ * This class is responsible for the settings required for the logic of autocomplete,
+ * external events such as adding libraries, creating new files, etc .. will be monitored.
+ * Filtering and decision will appear in the autocomplete is up to the: {@link CompletionProviderWithContext}.
+ * Another class that works together is the: {@link RealtimeCompletionsListener} ,
+ * that monitor real-time changes to the text and notifies when it should be made a new parser.
+ *
+ * The analysis(parser) of the source code is made by the library cplus-libparser
, Which was specially developed
+ * for the Arduino, more can be used in other projects.
+ *
+ * @author Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ * @date 22/11/2014
+ */
+public class SketchCompletionProvider extends LanguageAwareCompletionProvider implements LibraryListener, LibraryIndexListener, SketchListener{
+
+ private final static Logger LOG = Logger.getLogger(RealtimeCompletionsListener.class.getName());
+
+ public static final String SKETCH_LIB_PREFIX = ArduinoLibraryScanner.SKETCH_LIB_PREFIX;
+
+ /**
+ * Matches strings like {@code obj.myMethod(params)}
+ * {@code (?U)} lets {@code \\w} also match non-ASCII letters.
+ */
+ public static final Pattern INSTANCE_CALL_REGEX = Pattern.compile("(?U)([.\\w]+)\\.([\\w]+)\\s*\\((.*)\\)");
+
+ public static final Pattern FUNCTION_CALL_REGEX = Pattern.compile("(?U)([.\\w]+)\\s*\\((.*)\\)");
+
+ private TLibrary sketchLibrary; // classes, variables, functions of sketch
+ private SketchData sketchData;
+ private LibraryList importedLibraries; // same instance in Sketch
+
+ private RealtimeCompletionsListener realtimeCompletionsListener;
+
+ private CompletionProviderWithContext provider = new CompletionProviderWithContext(); // Loaded static auto-completes.
+
+ private AutoCompletion autoCompletion;
+
+ public SketchCompletionProvider(SketchData sketchData) {
+ super();
+ this.sketchData = sketchData;
+
+ provider.setParameterChoicesProvider(new ParameterChoicesProvider(this));
+ setDefaultCompletionProvider(provider);
+ provider.setParameterizedCompletionParams('(', ", ", ')');
+
+ LibraryIndex.addListener(this);
+ sketchData.addListener(this);
+ realtimeCompletionsListener = new RealtimeCompletionsListener(sketchData);
+
+ // Import existing...
+
+ // Arduino Core
+ //=======================
+ TargetPlatform targetPlatform = BaseNoGui.getTargetPlatform();
+ File folder = targetPlatform.getFolder();
+ File coreFolder = new File(folder,"cores"+File.separator+"arduino");
+ if(coreFolder.exists()){
+ UserLibrary coreLib;
+ try {
+ coreLib = UserLibrary.create(coreFolder);
+ LibraryIndex.scanFolder(coreFolder, new ArduinoLibraryScanner(coreLib)); // fire #onLoadLibrary on finish
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ LibraryIndex.scanFolder(sketchData.getFolder(), new SketchCodeScanner(sketchData)); // fire #onLoadLibrary on finish
+
+
+ onSketchLoad(sketchData);
+ for (SketchCode sketchCode : sketchData.getCodes()) {
+ onSketchInserted(sketchData, sketchCode);
+ }
+
+ loadDefaultAutocompletes();
+ }
+
+
+ /**
+ * Remove all listeners
+ */
+ public void uninstall() {
+ LibraryIndex.removeListener(this);
+ LibraryIndex.removeLibrary(sketchLibrary);
+ sketchData.removeListener(this);
+ importedLibraries.removeListener(this);
+
+ autoCompletion.getTextComponent().removeKeyListener(realtimeCompletionsListener);
+
+ for (SketchCode code : sketchData.getCodes()) {
+ Document document = getDocument(code);
+ if(document != null)
+ document.removeDocumentListener(realtimeCompletionsListener);
+ }
+ }
+
+
+ // ==========================================
+ // Sketch Library (importedLibraries) Listener
+ // ==========================================
+
+ @Override
+ public void onInsertLibrary(UserLibrary library) {
+
+ if(isExternalMode()) return;
+
+ LOG.fine("Arduino Lib: " + library);
+ LibraryIndex.scanFolder(library.getSrcFolder(), new ArduinoLibraryScanner(library)); // scan lib and fire #onLoadLibrary
+ }
+
+ @Override
+ public void onRemoveLibrary(UserLibrary library) {
+
+ if(isExternalMode()) return;
+
+ LOG.fine("Arduino Lib: " + library);
+ }
+
+ @Override
+ public void onClearLibraryList() {
+
+ if(isExternalMode()) return;
+
+ }
+
+
+ // ==========================================
+ // SketchCode Listener
+ // ==========================================
+
+ @Override
+ public void onSketchLoad(SketchData sketch) {
+
+ if(isExternalMode()) return;
+
+ LOG.fine(sketch.getName());
+
+ importedLibraries = sketch.getImportedLibraries();
+ importedLibraries.addListener(this);
+ for (UserLibrary library : importedLibraries) {
+ onInsertLibrary(library);
+ }
+ }
+
+
+ @Override
+ public void onSketchInserted(SketchData sketch, SketchCode code) {
+
+ if(isExternalMode()) return;
+
+ LOG.fine(code.getFileName());
+
+ Object metadata = code.getMetadata();
+ if(metadata instanceof SketchDocumentProvider){
+ Document document = ((SketchDocumentProvider) metadata).getDocument();
+ if(document != null){
+ document.addDocumentListener(realtimeCompletionsListener);
+ }
+ }
+
+ }
+
+ @Override
+ public void onSketchSaved(SketchData sketch, SketchCode code) {
+
+ if(isExternalMode()) return;
+
+ LOG.fine(code.getFileName());
+
+ if(sketchLibrary != null){
+ sketchLibrary.clear(code.getFile().getPath()); // Clear to get the new variables and remove those that no longer exist
+ }
+
+ LibraryIndex.scanFolder(sketch.getFolder(), new SketchCodeScanner(sketch, code)); // fire #onLoadLibrary on finish
+ }
+
+
+ // ==========================================
+ // LibraryIndex Listener (Parser)
+ // ==========================================
+
+ @Override
+ public void onLoadLibrary(TLibrary library) {
+
+ if(isExternalMode()) return;
+
+ if(library.name().equals(SKETCH_LIB_PREFIX+sketchData.getName())){ // Sketch indexing finish
+ sketchLibrary = library;
+ sketchLibrary.setReloadable(true);
+ provider.setSketchLibrary(sketchLibrary);
+ sketchData.setSketchMetadata(sketchLibrary);
+ }
+
+ createCompletions(library);
+ }
+
+ @Override
+ public void onUnloadLibrary(TLibrary library) {
+ LOG.fine(library.name());
+
+ }
+
+ @Override
+ public void onReloadLibrary(TLibrary library) {
+
+ if(isExternalMode()) return;
+
+ createCompletions(library);
+ }
+
+ private boolean isExternalMode(){
+ return PreferencesData.getBoolean("editor.external");
+ }
+
+ protected void loadDefaultAutocompletes(){
+
+ List completions = new ArrayList();
+
+ completions.add(new IncludeTemplate(provider));
+ completions.add(new TemplateCompletion(provider, "for", "interate over array", "for (int ${i} = 0; ${i} < ${array}.length; ${i}++) {\n\t${cursor}\n}"));
+ completions.add(new TemplateCompletion(provider, "while", "while block", "while (${condition}) {\n\t${cursor}\n}"));
+ completions.add(new TemplateCompletion(provider, "if", "if block", "if (${condition}) {\n\t${cursor}\n}"));
+ completions.add(new TemplateCompletion(provider, "elseif", "elseif block", "else if (${condition}) {\n\t${cursor}\n}"));
+ completions.add(new TemplateCompletion(provider, "else", "else block", "else{\n\t${cursor}\n}"));
+
+ completions.add(new TemplateCompletion(provider, "println", "Serial.println()", "Serial.println(\"${cursor}\");"));
+
+ completions.add(new TemplateCompletion(provider, "dw", "digitalWrite", "digitalWrite(${cursor});"));
+ completions.add(new TemplateCompletion(provider, "dr", "digitalRead", "digitalRead(${cursor});"));
+ completions.add(new TemplateCompletion(provider, "aw", "analogWrite", "analogWrite(${cursor});"));
+ completions.add(new TemplateCompletion(provider, "ar", "analogRead", "analogRead(${cursor});"));
+
+
+ //Add as ENUNM
+ // TODO: only show if in method params
+ String[] names = {"HIGH", "LOW", "OUTPUT", "INPUT", "INPUT_PULLUP", "CHANGE", "FALLING", "RISING", "RISING", "DEC", "HEX", "OCT", "BIN", "LED_BUILTIN"};
+ for (String name : names) {
+ TAttribute attribute = new TAttribute("int", name);
+ attribute.setEnum(true);
+ completions.add(new TElementCompletion(provider, attribute));
+ }
+
+ provider.addCompletions(completions);
+ }
+
+
+ /**
+ * Add Completions from parsed lib
+ */
+ protected void createCompletions( TLibrary library ) {
+
+ LOG.fine("build auto-complete for: " + library.name());
+
+ Set allMembers = library.getAllMembers();
+
+ // Sketch indexing finish
+ // sketchCompletions are dynamic.
+ if (sketchLibrary != null && library.name().equals(sketchLibrary.name())) {
+
+ List sketchCompletions = new ArrayList();
+
+ for (TElement element : allMembers) {
+
+ // Set sketck attrs as not static
+ if (element instanceof TAttribute) {
+ ((TAttribute) element).setStatic(false);
+ }
+
+ // track positions of methods and variables even after document changes
+ TElementLocation location = element.getLocation();
+ if (location != null) {
+ Document document = findSketchDocument(element);
+ // If if document already loaded
+ if (document != null) {
+ TDynamicLocation dynamicLocation = new TDynamicLocation(document, location);
+ element.setLocation(dynamicLocation);
+ }
+ }
+
+ if (element instanceof TFunction) {
+ if (element.name().equals("setup") || element.name().equals("loop")) continue;
+ TFunctionCompletion completion = new TFunctionCompletion(provider, (TFunction) element);
+ completion.setRelevance(3);
+ sketchCompletions.add(completion);
+ } else {
+ sketchCompletions.add(new TElementCompletion(provider, element));
+ }
+ }
+
+ provider.setSketchCompletions(sketchCompletions);
+
+ } else {
+
+ List staticCompletions = new ArrayList();
+
+ Set classes = library.getClasses();
+ for (TClass tClass : classes) {
+ // XXX autocomplete: PdeTokenMaker.addKeyword(tClass.name(), Token.DATA_TYPE);
+ }
+
+ for (TElement element : allMembers) {
+ if (element instanceof TFunction) { // global func.
+ if (element.name().equals("setup") || element.name().equals("loop")) continue;
+ TFunctionCompletion completion = new TFunctionCompletion(provider, (TFunction) element);
+ staticCompletions.add(completion);
+ } else {
+ staticCompletions.add(new TElementCompletion(provider, element));
+ }
+ }
+
+ provider.addCompletions(staticCompletions);
+
+ }
+
+ }
+
+ protected Document findSketchDocument(TElement element){
+
+ TElementLocation location = element.getLocation();
+
+ String name = location.getFileName();
+
+ SketchCode[] codes = sketchData.getCodes();
+
+ if(codes.length == 1) return getDocument(codes[0]);
+
+ for (SketchCode sketchCode : codes) {
+ if(sketchCode.getFileName().equals(name)){
+ return getDocument(sketchCode);
+ }
+ }
+
+ return null;
+ }
+
+ static Document getDocument(SketchCode code){
+ Object metadata = code.getMetadata();
+ if(metadata instanceof SketchDocumentProvider){
+ return ((SketchDocumentProvider) metadata).getDocument();
+ }
+ return null;
+ }
+
+ public SketchData getSketchData() {
+ return sketchData;
+ }
+
+ public TFunction getCurrentFunctionScope(RSyntaxTextArea textarea){
+ return provider.getCurrentFunctionScope(textarea);
+ }
+
+
+ public void generateNewVariableFor(String expression, int startOffSet) {
+
+ Matcher instanceCall = INSTANCE_CALL_REGEX.matcher(expression);
+
+ String returnType = null;
+ String function = null;
+ String varname = null;
+
+ RSyntaxTextArea textArea = (RSyntaxTextArea) autoCompletion.getTextComponent();
+
+ // find retun type of function like (obj.myMethod(params))
+ if (instanceCall.find()) {
+ String instance = instanceCall.group(1);
+ function = instanceCall.group(2);
+
+ Set variables = new HashSet();
+
+ variables.addAll(sketchLibrary.getGlobalVariables());
+
+ TFunction functionScope = provider.getCurrentFunctionScope(textArea);
+ if(functionScope != null){
+ variables.addAll(functionScope.getLocalVariables());
+ }
+
+ TClass varClass = null;
+
+ for (TAttribute var : variables) {
+
+ LOG.fine("generateVariableName , var : " + var);
+
+ // find class of instance.
+ if(var.name().equals(instance)){
+ LOG.fine("generateVariableName , found : " + var);
+
+ String type = var.getType();
+ varClass = LibraryIndex.getClass(type);
+ if(varClass != null) break;
+ }
+
+ }
+
+ // Find like: Serial / Ethernet.
+ if(varClass == null){
+ varClass = LibraryIndex.getClass(instance);
+ }
+
+ // Find like: EEPROM (static struct)
+ if(varClass == null){
+
+ TLibrary library = LibraryIndex.getLibrary(instance);
+ if(library != null){
+ TElement variable = library.findMember(instance);
+ if(variable instanceof TAttribute){
+ varClass = LibraryIndex.getClass(((TAttribute) variable).getType());
+ }
+
+ }
+
+ }
+
+ if(varClass != null){
+
+ LOG.fine("Class : " +varClass + "");
+ TFunction tFunction = varClass.getFunction(function, true);
+
+ LOG.fine("Function = " +tFunction + " (for:" + function + ")");
+
+ if(tFunction != null){
+ returnType = tFunction.getReturnType();
+ }
+
+ }
+
+
+ }else{
+
+ Matcher functionCall = FUNCTION_CALL_REGEX.matcher(expression);
+ if (functionCall.find()) {
+ function = functionCall.group(1);
+ String param = functionCall.group(2);
+
+ if(function.equals("digitalRead") || function.equals("analoadRead")){
+ returnType = "int";
+ varname = param +"Val";
+ }else{
+ Set functions = LibraryIndex.getGlobalFunctions(function);
+
+ if(!functions.isEmpty()){
+ returnType = functions.iterator().next().getReturnType();
+ }
+ }
+
+ }
+
+ }
+
+
+ if(returnType != null){
+
+ if(varname == null){
+ if(TElement.isPrimitive(returnType)){
+ varname = function;
+ }else{
+ String lastWord = StringUtils.findLastWord(returnType);
+ if(lastWord == null) lastWord = returnType;
+ varname = StringUtils.uncapitalize(lastWord);
+ }
+ }
+
+ if(varname != null){
+
+ GenerateVarTemplate completion = new GenerateVarTemplate(provider, returnType, varname);
+
+ textArea.setCaretPosition(startOffSet);
+
+ AutoCompletion autoCompletion = getAutoCompletion();
+ autoCompletion.startParameterizedCompletionAssistance(completion, false);
+
+ }
+ }
+
+ }
+
+
+ public void setAutoCompletion(AutoCompletion autoCompletion) {
+ this.autoCompletion = autoCompletion;
+ autoCompletion.getTextComponent().addKeyListener(realtimeCompletionsListener);
+ }
+
+ public AutoCompletion getAutoCompletion() {
+ return autoCompletion;
+ }
+
+
+
+
+}
diff --git a/arduino-autocomplete/src/cc/arduino/packages/autocomplete/TAttributeFilter.java b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/TAttributeFilter.java
new file mode 100755
index 00000000000..e0110b522e3
--- /dev/null
+++ b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/TAttributeFilter.java
@@ -0,0 +1,46 @@
+/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
+
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ * Copyright 2015 Arduino LLC
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+package cc.arduino.packages.autocomplete;
+
+import br.com.criativasoft.cpluslibparser.metadata.TAttribute;
+
+/**
+ * Simple collections filter
+ * @author Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ */
+public class TAttributeFilter extends TElementFilter {
+
+ public TAttributeFilter(String text, int mathType) {
+ super(text, mathType);
+ }
+
+}
diff --git a/arduino-autocomplete/src/cc/arduino/packages/autocomplete/TDynamicLocation.java b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/TDynamicLocation.java
new file mode 100755
index 00000000000..732560779a9
--- /dev/null
+++ b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/TDynamicLocation.java
@@ -0,0 +1,151 @@
+/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
+
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ * Copyright 2015 Arduino LLC
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+package cc.arduino.packages.autocomplete;
+
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Document;
+import javax.swing.text.Element;
+import javax.swing.text.Position;
+
+import br.com.criativasoft.cpluslibparser.metadata.TElement;
+import br.com.criativasoft.cpluslibparser.metadata.TElementLocation;
+
+/**
+ * Element to track positions of methods and variables even after document changes.
+ * This feature is implemented by the swing api ({@link Position})
+ * @author Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ */
+public class TDynamicLocation extends TElementLocation {
+
+ private Document document;
+ private Position startOffs;
+ private Position endOffs;
+
+ private int lastEndOffs = -1;
+ private int cachedEndLine;
+ private TElementLocation reference;
+
+ public TDynamicLocation(Document document, TElement element) {
+ this(document, element.getLocation());
+ element.setLocation(this);
+ }
+
+ public TDynamicLocation(Document document, TElementLocation reference) {
+ super();
+ this.document = document;
+ try {
+ this.startOffs = document.createPosition(reference.getStartOffset());
+ this.endOffs = document.createPosition(reference.getEndOffset());
+ this.reference = reference;
+ } catch (BadLocationException e) {
+ e.printStackTrace();
+ }
+ }
+
+
+
+ /**
+ * Returns whether the specified offset is "inside". This method
+ * returns true
if the offset is greater than the element start
+ * offset, and no further than the last offset of the last element line.
+ *
+ * @param offs The offset to check.
+ * @return Whether the offset is "inside" the element.
+ * @see #containsLine(int)
+ */
+ public boolean containsOffset(int offs) {
+ boolean contained = false;
+ if (offs>getStartOffset()) {
+ // Use Elements to avoid BadLocationExceptions
+ Element root = document.getDefaultRootElement();
+ int line = root.getElementIndex(offs);
+ contained = line<=getEndLine();
+ }
+ return contained;
+ }
+
+ /**
+ * Returns the end line of this Element.
+ *
+ * The value returned by this method will automatically update as the
+ * text area's contents are modified, to track the ending line of the
+ * code block.
+ *
+ * @return The end line of this code block.
+ * @see #getEndOffset()
+ */
+ public int getEndLine() {
+ int endOffs = getEndOffset();
+ if (lastEndOffs==endOffs) {
+ return cachedEndLine;
+ }
+ lastEndOffs = endOffs;
+ Element root = document.getDefaultRootElement();
+ return cachedEndLine = root.getElementIndex(endOffs);
+ }
+
+
+ /**
+ * Returns the starting offset of this Element.
+ *
+ * The value returned by this method will automatically update as the
+ * text area's contents are modified, to track the starting offset of the
+ * code block.
+ *
+ * @return The start offset of this fold.
+ * @see #getEndOffset()
+ */
+ public int getStartOffset() {
+ return startOffs.getOffset();
+ }
+
+ /**
+ * Returns the end offset of this Element.
+ *
+ * The value returned by this method will automatically update as the
+ * text area's contents are modified, to track the ending offset of the
+ * code block.
+ *
+ * @return The end offset of this code block.
+ * @see #getEndLine()
+ */
+ public int getEndOffset() {
+ return endOffs!=null ? endOffs.getOffset() : Integer.MAX_VALUE;
+ }
+
+
+ @Override
+ public String toString() {
+ return "["+getStartOffset()+", "+getEndOffset()+"], orig: " + reference.toString();
+ }
+
+}
diff --git a/arduino-autocomplete/src/cc/arduino/packages/autocomplete/TElementCompletion.java b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/TElementCompletion.java
new file mode 100755
index 00000000000..90af82d77a2
--- /dev/null
+++ b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/TElementCompletion.java
@@ -0,0 +1,139 @@
+/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
+
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ * Copyright 2015 Arduino LLC
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+package cc.arduino.packages.autocomplete;
+
+import org.fife.ui.autocomplete.AbstractCompletion;
+import org.fife.ui.autocomplete.CompletionProvider;
+
+import br.com.criativasoft.cpluslibparser.metadata.*;
+
+public class TElementCompletion extends AbstractCompletion {
+
+ private TElement element;
+ private String alreadyEntered;
+
+ public TElementCompletion(CompletionProvider provider, TElement element) {
+ super(provider);
+ this.element = element;
+ }
+
+ public TElementCompletion(CompletionProvider provider, TElement element, String alreadyEntered) {
+ super(provider);
+ this.element = element;
+ this.alreadyEntered = alreadyEntered;
+ }
+
+ @Override
+ public String getReplacementText() {
+
+ if(alreadyEntered == null || alreadyEntered.length() == 0) return element.name();
+
+ return alreadyEntered + element.name();
+ }
+
+ @Override
+ public String getSummary() {
+ return element.toString();
+ }
+
+ @Override
+ public String getInputText() {
+ return element.name();
+ }
+
+ public TElement getElement() {
+ return element;
+ }
+
+ public String getShortDescription(){
+ return element.name();
+ }
+
+
+ public CompletionType getType(){
+
+ if(element instanceof TLibrary){
+ return CompletionType.LIBRARY;
+ }
+
+ if(element instanceof TClass){
+ return CompletionType.CLASS;
+ }
+
+ if(element instanceof TFunction){
+ return CompletionType.FUNCTION;
+ }
+
+ if(element instanceof TAttribute){
+ TAttribute attribute = (TAttribute) element;
+ if(attribute.isLocal()) return CompletionType.LOCAL_VAR;
+ if(attribute.isEnum()) return CompletionType.ENUM;
+ if(attribute.isStatic()) return CompletionType.STATIC_VAR;
+ return CompletionType.VARIABLE;
+ }
+
+ return CompletionType.VARIABLE;
+
+ }
+
+
+ @Override
+ public int getRelevance() {
+ if(element instanceof TLibrary){
+ return 1;
+ }
+
+ if(element instanceof TClass){
+ return 2;
+ }
+
+ if(element instanceof TFunction){
+ return 3;
+ }
+
+ if(element instanceof TAttribute){
+ TAttribute attribute = (TAttribute) element;
+ if(attribute.isLocal()) return 7;
+ if(attribute.isEnum()) return 5;
+ if(attribute.isStatic()) return 4;
+ return 6;
+ }
+
+ return 0;
+ }
+
+ @Override
+ public String toString() {
+ return element.name();
+ }
+
+}
diff --git a/arduino-autocomplete/src/cc/arduino/packages/autocomplete/TElementFilter.java b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/TElementFilter.java
new file mode 100755
index 00000000000..94737c71bbe
--- /dev/null
+++ b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/TElementFilter.java
@@ -0,0 +1,77 @@
+/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
+
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ * Copyright 2015 Arduino LLC
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+package cc.arduino.packages.autocomplete;
+
+import processing.app.helpers.IPredicate;
+import br.com.criativasoft.cpluslibparser.metadata.TElement;
+
+/**
+ * Simple collections filter
+ * @author Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ */
+public class TElementFilter implements IPredicate {
+
+ public static final int MATCH_START = 1;
+ public static final int MATCH_CONTAINS = 2;
+ public static final int MATCH_END = 3;
+
+ private String text;
+
+ private int mathType = MATCH_START;
+
+
+ public TElementFilter(String text, int mathType) {
+ super();
+ this.text = text;
+ this.mathType = mathType;
+ }
+
+
+ @Override
+ public boolean apply(TElement node) {
+ String name = node.name().toLowerCase();
+
+ if(mathType == MATCH_START){
+ return name.startsWith(text);
+ }
+ if(mathType == MATCH_CONTAINS){
+ return name.contains(text);
+ }
+ if(mathType == MATCH_END){
+ return name.endsWith(text);
+ }
+
+ return false;
+ }
+
+
+}
diff --git a/arduino-autocomplete/src/cc/arduino/packages/autocomplete/TFunctionCompletion.java b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/TFunctionCompletion.java
new file mode 100755
index 00000000000..c26727725ee
--- /dev/null
+++ b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/TFunctionCompletion.java
@@ -0,0 +1,122 @@
+/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
+
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ * Copyright 2015 Arduino LLC
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+package cc.arduino.packages.autocomplete;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import org.fife.ui.autocomplete.CompletionProvider;
+import org.fife.ui.autocomplete.FunctionCompletion;
+
+import br.com.criativasoft.cpluslibparser.metadata.TFunction;
+import br.com.criativasoft.cpluslibparser.metadata.TParam;
+
+public class TFunctionCompletion extends FunctionCompletion {
+
+ private TFunction function;
+ private String alreadyEntered;
+
+ public TFunctionCompletion(CompletionProvider provider, TFunction function) {
+ this(provider, function, null);
+ }
+
+ public TFunctionCompletion(CompletionProvider provider, TFunction function, String alreadyEntered) {
+ super(provider, function.name(), function.getReturnType());
+ this.function = function;
+ this.alreadyEntered = alreadyEntered;
+
+ Set params = function.getParams();
+ List list = new LinkedList();
+
+ for (TParam param : params) {
+ list.add(new TFunctionParam(param, function));
+ }
+
+ setParams(list);
+ }
+
+ public TFunction getFunction() {
+ return function;
+ }
+
+ @Override
+ public String getShortDescription() {
+ return function.toDeclarationString();
+ }
+
+ @Override
+ public String getInputText() {
+ return function.name();
+ }
+
+
+ @Override
+ public String getReplacementText() {
+
+ if(alreadyEntered == null || alreadyEntered.length() == 0) return super.getReplacementText();
+
+ return alreadyEntered + super.getReplacementText();
+ }
+
+ @Override
+ public int getRelevance() {
+ return 3;
+ }
+
+ @Override
+ public String toString() {
+ return function.name();
+ }
+
+ public static class TFunctionParam extends Parameter{
+
+ private TParam param;
+ private TFunction function;
+
+ public TFunctionParam(TParam attribute, TFunction function) {
+ super(attribute.getType(), attribute.name());
+ this.param = attribute;
+ this.function = function;
+ }
+
+ public TFunction getFunction() {
+ return function;
+ }
+
+ public TParam getAttributeParam() {
+ return param;
+ }
+
+ }
+
+}
diff --git a/arduino-autocomplete/src/cc/arduino/packages/autocomplete/TFunctionFilter.java b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/TFunctionFilter.java
new file mode 100755
index 00000000000..c1a0a54167b
--- /dev/null
+++ b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/TFunctionFilter.java
@@ -0,0 +1,46 @@
+/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
+
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ * Copyright 2015 Arduino LLC
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+package cc.arduino.packages.autocomplete;
+
+import br.com.criativasoft.cpluslibparser.metadata.TFunction;
+
+/**
+ * Simple collections filter
+ * @author Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ */
+public class TFunctionFilter extends TElementFilter{
+
+ public TFunctionFilter(String text, int mathType) {
+ super(text, mathType);
+ }
+
+}
diff --git a/arduino-autocomplete/src/cc/arduino/packages/autocomplete/TemplateChoicesCompletion.java b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/TemplateChoicesCompletion.java
new file mode 100755
index 00000000000..f2b6eb7217a
--- /dev/null
+++ b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/TemplateChoicesCompletion.java
@@ -0,0 +1,67 @@
+/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
+
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ * Copyright 2015 Arduino LLC
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+package cc.arduino.packages.autocomplete;
+
+import java.util.List;
+
+import org.fife.ui.autocomplete.Completion;
+import org.fife.ui.autocomplete.CompletionProvider;
+import org.fife.ui.autocomplete.ParameterizedCompletion;
+import org.fife.ui.autocomplete.TemplateCompletion;
+
+/**
+ * Base class for templates that provide assistance to autocomplete parameters
+ * @see ParameterizedCompletion
+ * @see ParameterChoicesProvider
+ * @author Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ * @date 09/12/2014
+ */
+public abstract class TemplateChoicesCompletion extends TemplateCompletion {
+
+ public TemplateChoicesCompletion(CompletionProvider provider,
+ String inputText, String definitionString,
+ String template) {
+ super(provider, inputText, definitionString, template);
+ }
+
+ public TemplateChoicesCompletion(CompletionProvider provider,
+ String inputText, String definitionString,
+ String template, String shortDescription,
+ String summary) {
+ super(provider, inputText, definitionString, template, shortDescription,summary);
+ }
+
+
+ public abstract List getChoices(Parameter param);
+
+
+}
diff --git a/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/class.gif b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/class.gif
new file mode 100755
index 00000000000..e4c2a836f83
Binary files /dev/null and b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/class.gif differ
diff --git a/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/enum.gif b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/enum.gif
new file mode 100755
index 00000000000..15535f52f52
Binary files /dev/null and b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/enum.gif differ
diff --git a/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/error.gif b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/error.gif
new file mode 100755
index 00000000000..0bc60689c6d
Binary files /dev/null and b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/error.gif differ
diff --git a/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/field_default_obj.gif b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/field_default_obj.gif
new file mode 100755
index 00000000000..6929d3d13f2
Binary files /dev/null and b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/field_default_obj.gif differ
diff --git a/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/field_public_obj.gif b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/field_public_obj.gif
new file mode 100755
index 00000000000..d4cb4254d92
Binary files /dev/null and b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/field_public_obj.gif differ
diff --git a/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/function.gif b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/function.gif
new file mode 100755
index 00000000000..7d24707ee82
Binary files /dev/null and b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/function.gif differ
diff --git a/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/function_static.gif b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/function_static.gif
new file mode 100755
index 00000000000..e02dc63568c
Binary files /dev/null and b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/function_static.gif differ
diff --git a/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/int_obj.gif b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/int_obj.gif
new file mode 100755
index 00000000000..2ebc46e1d3b
Binary files /dev/null and b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/int_obj.gif differ
diff --git a/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/jdoc_tag_obj.gif b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/jdoc_tag_obj.gif
new file mode 100755
index 00000000000..c43c5d51c51
Binary files /dev/null and b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/jdoc_tag_obj.gif differ
diff --git a/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/static_co.gif b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/static_co.gif
new file mode 100755
index 00000000000..6119fb446f4
Binary files /dev/null and b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/static_co.gif differ
diff --git a/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/template_obj.gif b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/template_obj.gif
new file mode 100755
index 00000000000..fdde5fbb95e
Binary files /dev/null and b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/template_obj.gif differ
diff --git a/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/variable.gif b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/variable.gif
new file mode 100755
index 00000000000..f4a1ea15070
Binary files /dev/null and b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/variable.gif differ
diff --git a/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/variable_local.gif b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/variable_local.gif
new file mode 100755
index 00000000000..8adce9541f1
Binary files /dev/null and b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/variable_local.gif differ
diff --git a/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/variable_static.gif b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/variable_static.gif
new file mode 100755
index 00000000000..c63eb8506b0
Binary files /dev/null and b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/icons/variable_static.gif differ
diff --git a/arduino-autocomplete/src/cc/arduino/packages/autocomplete/template/GenerateVarTemplate.java b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/template/GenerateVarTemplate.java
new file mode 100755
index 00000000000..5462bf29349
--- /dev/null
+++ b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/template/GenerateVarTemplate.java
@@ -0,0 +1,63 @@
+/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
+
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ * Copyright 2015 Arduino LLC
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+package cc.arduino.packages.autocomplete.template;
+
+import org.fife.ui.autocomplete.CompletionProvider;
+import org.fife.ui.autocomplete.TemplateCompletion;
+
+import cc.arduino.packages.autocomplete.SketchCompletionProvider;
+
+/**
+ * Used in {@link SketchCompletionProvider#generateNewVariableFor(String, int)}
+ * @author Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ * @date 11/12/2014
+ */
+public class GenerateVarTemplate extends TemplateCompletion {
+
+ private String type, name;
+
+ public GenerateVarTemplate(CompletionProvider provider,String type, String name) {
+ super(provider, name, name, type + " ${" + name + "} = ");
+ this.type = type;
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+
+}
diff --git a/arduino-autocomplete/src/cc/arduino/packages/autocomplete/template/IncludeTemplate.java b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/template/IncludeTemplate.java
new file mode 100755
index 00000000000..cfaf9dc4529
--- /dev/null
+++ b/arduino-autocomplete/src/cc/arduino/packages/autocomplete/template/IncludeTemplate.java
@@ -0,0 +1,110 @@
+/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
+
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ * Copyright 2015 Arduino LLC
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+package cc.arduino.packages.autocomplete.template;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.fife.ui.autocomplete.BasicCompletion;
+import org.fife.ui.autocomplete.Completion;
+import org.fife.ui.autocomplete.CompletionProvider;
+
+import br.com.criativasoft.cpluslibparser.LibraryIndex;
+import br.com.criativasoft.cpluslibparser.metadata.TLibrary;
+import processing.app.BaseNoGui;
+import processing.app.helpers.filefilters.OnlyFilesWithExtension;
+import processing.app.packages.LibraryList;
+import processing.app.packages.UserLibrary;
+import cc.arduino.packages.autocomplete.SketchCompletionProvider;
+import cc.arduino.packages.autocomplete.TemplateChoicesCompletion;
+
+public class IncludeTemplate extends TemplateChoicesCompletion {
+
+ public IncludeTemplate(CompletionProvider provider) {
+ super(provider, "#include", "#include <>", "#include ${<}");
+ }
+
+ @Override
+ public List getChoices(Parameter param) {
+ List completions = new LinkedList();
+
+ LibraryList libraries = BaseNoGui.getLibraries();
+ for (UserLibrary library : libraries) {
+ completions.add(new IncludeCompletion(getProvider(), library));
+ }
+
+ // Get files from Sketch folder.
+ Collection libs = LibraryIndex.getLibraries().values();
+ for (TLibrary tLibrary : libs) {
+ if(tLibrary.getName().startsWith(SketchCompletionProvider.SKETCH_LIB_PREFIX)){
+ File folder = new File(tLibrary.getLocation().getPath());
+ File[] listOfFiles = folder.listFiles(new OnlyFilesWithExtension(".h"));
+ if (listOfFiles != null) {
+ for (int i = 0; i < listOfFiles.length; i++) {
+ completions.add(new BasicCompletion(getProvider(), "\""+listOfFiles[i].getName()+"\""));
+ }
+ }
+ }
+ }
+
+ return completions;
+ }
+
+ private static class IncludeCompletion extends BasicCompletion{
+
+ private UserLibrary library;
+
+ public IncludeCompletion(CompletionProvider provider, UserLibrary library) {
+ super(provider, library.getInstalledFolder().getName());
+ this.library = library;
+ }
+
+ @Override
+ public String getSummary() {
+ return library.getSentence();
+ }
+
+ @Override
+ public String getShortDescription() {
+ return library.getName();
+ }
+
+ @Override
+ public String getReplacementText() {
+ return "<"+library.getInstalledFolder().getName()+".h>";
+ }
+
+ }
+
+}
diff --git a/arduino-core/.classpath b/arduino-core/.classpath
index b0e162044ae..e0cb4e783bc 100644
--- a/arduino-core/.classpath
+++ b/arduino-core/.classpath
@@ -18,6 +18,8 @@
+
+
@@ -29,5 +31,6 @@
+
diff --git a/arduino-core/build.xml b/arduino-core/build.xml
index 6245ed6b5c0..baf01440442 100644
--- a/arduino-core/build.xml
+++ b/arduino-core/build.xml
@@ -5,6 +5,9 @@
+
+
+
diff --git a/arduino-core/src/processing/app/BaseNoGui.java b/arduino-core/src/processing/app/BaseNoGui.java
index 640f2d757c6..0a88692dea2 100644
--- a/arduino-core/src/processing/app/BaseNoGui.java
+++ b/arduino-core/src/processing/app/BaseNoGui.java
@@ -7,10 +7,13 @@
import cc.arduino.files.DeleteFilesOnShutdown;
import cc.arduino.packages.DiscoveryManager;
import cc.arduino.packages.Uploader;
+
import com.fasterxml.jackson.core.JsonProcessingException;
+
import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.logging.impl.LogFactoryImpl;
import org.apache.commons.logging.impl.NoOpLog;
+
import processing.app.debug.Compiler;
import processing.app.debug.*;
import processing.app.helpers.*;
@@ -23,6 +26,7 @@
import java.io.*;
import java.net.URISyntaxException;
import java.util.*;
+import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -65,15 +69,14 @@ public class BaseNoGui {
// maps #included files to their library folder
public static Map importToLibraryTable;
- // maps library name to their library folder
- static private LibraryList libraries;
-
// XXX: Remove this field
static private List librariesFolders;
static UserNotifier notifier = new BasicUserNotifier();
static public Map packages;
+
+ static List enabledLoggers = new ArrayList();
static Platform platform;
@@ -243,7 +246,7 @@ static public String getHardwarePath() {
}
static public LibraryList getLibraries() {
- return libraries;
+ return librariesIndexer.getInstalledLibraries();
}
static public List getLibrariesPath() {
@@ -599,6 +602,43 @@ protected static void dumpPrefs(CommandlineParser parser) {
static public void initLogger() {
System.setProperty(LogFactoryImpl.LOG_PROPERTY, NoOpLog.class.getCanonicalName());
Logger.getLogger("javax.jmdns").setLevel(Level.OFF);
+
+ Handler consoleHandler = new ConsoleLogger();
+ consoleHandler.setLevel(Level.ALL);
+ consoleHandler.setFormatter(new LogFormatter("%1$tl:%1$tM:%1$tS [%4$7s] %2$s: %5$s%n"));
+
+ Logger globalLogger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
+ globalLogger.setLevel(consoleHandler.getLevel());
+
+ // Remove default
+ Handler[] handlers = globalLogger.getHandlers();
+ for(Handler handler : handlers) {
+ globalLogger.removeHandler(handler);
+ }
+ Logger root = Logger.getLogger("");
+ handlers = root.getHandlers();
+ for(Handler handler : handlers) {
+ root.removeHandler(handler);
+ }
+
+ globalLogger.addHandler(consoleHandler);
+ //root.addHandler(consoleHandler);
+
+ enableLogger("cc.arduino.packages.autocomplete");
+ enableLogger("br.com.criativasoft.cpluslibparser");
+ enableLogger(BaseNoGui.class.getPackage().getName());
+
+ }
+
+ static public void enableLogger(String name){
+
+ Logger globalLogger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
+
+ Logger logger = Logger.getLogger(name);
+
+ enabledLoggers.add(logger);
+
+ logger.setParent(globalLogger);
}
static public void initPackages() throws Exception {
diff --git a/arduino-core/src/processing/app/SketchData.java b/arduino-core/src/processing/app/SketchData.java
index cef17433e57..671bfad7eeb 100644
--- a/arduino-core/src/processing/app/SketchData.java
+++ b/arduino-core/src/processing/app/SketchData.java
@@ -1,5 +1,8 @@
package processing.app;
+import br.com.criativasoft.cpluslibparser.LibraryCache;
+import br.com.criativasoft.cpluslibparser.metadata.TLibrary;
+
import com.google.common.collect.FluentIterable;
import static processing.app.I18n._;
@@ -8,6 +11,11 @@
import java.io.IOException;
import java.util.*;
+import processing.app.packages.LibraryList;
+import processing.app.packages.SketchListener;
+import processing.app.packages.UserLibrary;
+import processing.app.preproc.PdePreprocessor;
+
public class SketchData {
public static final List SKETCH_EXTENSIONS = Arrays.asList("ino", "pde");
@@ -33,6 +41,21 @@ public class SketchData {
private String name;
private List codes = new ArrayList();
+
+ private Set listeners = new LinkedHashSet();
+
+ /**
+ * List of library folders.
+ */
+ private LibraryList importedLibraries = new LibraryList();
+
+ /** Sketch source metadata(classes, variables, functions), this is set in {@link SketchCompletionProvider#onLoadLibrary(TLibrary)} */
+ private transient TLibrary sketchMetadata;
+
+ /** Sketch and 'Libraries currently used' Metadata Cache - This is used by autocomplete */
+ private transient LibraryCache libraryCacheContext;
+
+ private transient SketchCode currentCode;
private static final Comparator CODE_DOCS_COMPARATOR = new Comparator() {
@Override
@@ -49,6 +72,9 @@ public int compare(SketchCode x, SketchCode y) {
String mainFilename = primaryFile.getName();
int suffixLength = getDefaultExtension().length() + 1;
name = mainFilename.substring(0, mainFilename.length() - suffixLength);
+
+ libraryCacheContext = new LibraryCache();
+ libraryCacheContext.setName(name);
folder = new File(file.getParent());
//System.out.println("sketch dir is " + folder);
@@ -146,6 +172,21 @@ protected void load() throws IOException {
break;
}
}
+
+ // Find used libraries
+ for (SketchCode code : getCodes()) {
+ List includes = PdePreprocessor.findIncludes(code.getProgram());
+ if(includes != null){
+ for (String include : includes) {
+ LibraryList libs = BaseNoGui.importToLibraryTable.get(include);
+ if(libs == null) continue;
+ UserLibrary lib = libs.get(0);
+ if (lib != null && !importedLibraries.contains(lib)) {
+ importedLibraries.add(lib);
+ }
+ }
+ }
+ }
// sort the entries at the top
sortCode();
@@ -153,8 +194,10 @@ protected void load() throws IOException {
public void save() throws IOException {
for (SketchCode code : getCodes()) {
- if (code.isModified())
+ if (code.isModified()){
code.save();
+ notifyListeners(SketchListener.Event.SAVED, code);
+ }
}
}
@@ -190,6 +233,7 @@ public String getMainFilePath() {
public void addCode(SketchCode sketchCode) {
codes.add(sketchCode);
+ notifyListeners(SketchListener.Event.INSERTED, sketchCode);
}
public void moveCodeToFront(SketchCode codeDoc) {
@@ -201,6 +245,7 @@ protected void replaceCode(SketchCode newCode) {
for (SketchCode code : codes) {
if (code.getFileName().equals(newCode.getFileName())) {
codes.set(codes.indexOf(code), newCode);
+ notifyListeners(SketchListener.Event.SAVED, newCode);
return;
}
}
@@ -235,6 +280,32 @@ public int indexOfCode(SketchCode who) {
}
return -1;
}
+
+ public boolean addListener(SketchListener listener){
+ return listeners.add(listener);
+ }
+
+ public boolean removeListener(SketchListener listener){
+ return listeners.add(listener);
+ }
+
+ public void notifyListeners(SketchListener.Event event, SketchCode code){
+
+ for (SketchListener listener : listeners) {
+
+ if(event == SketchListener.Event.LOAD){
+ listener.onSketchLoad(this);
+ }
+ if(event == SketchListener.Event.INSERTED){
+ listener.onSketchInserted(this, code);
+ }
+ if(event == SketchListener.Event.SAVED){
+ listener.onSketchSaved(this, code);
+ }
+
+ }
+
+ }
public String getName() {
return name;
@@ -259,4 +330,33 @@ public File getDataFolder() {
public File getCodeFolder() {
return codeFolder;
}
+
+ public void setSketchMetadata(TLibrary sketchMetadata) {
+ this.sketchMetadata = sketchMetadata;
+ }
+
+ public TLibrary getSketchMetadata() {
+ return sketchMetadata;
+ }
+
+ public LibraryCache getLibraryCacheContext() {
+ return libraryCacheContext;
+ }
+
+ public LibraryList getImportedLibraries() {
+ return importedLibraries;
+ }
+
+ public void addLibrary(UserLibrary lib) {
+ if(lib != null){
+ importedLibraries.add(lib);
+ }
+ }
+ public void setCurrentCode(SketchCode currentCode) {
+ this.currentCode = currentCode;
+ }
+
+ public SketchCode getCurrentCode() {
+ return currentCode;
+ }
}
diff --git a/arduino-core/src/processing/app/SketchDocumentProvider.java b/arduino-core/src/processing/app/SketchDocumentProvider.java
new file mode 100755
index 00000000000..b5eecf4a22a
--- /dev/null
+++ b/arduino-core/src/processing/app/SketchDocumentProvider.java
@@ -0,0 +1,9 @@
+package processing.app;
+
+import javax.swing.text.Document;
+
+public interface SketchDocumentProvider {
+
+ Document getDocument();
+
+}
diff --git a/arduino-core/src/processing/app/debug/Compiler.java b/arduino-core/src/processing/app/debug/Compiler.java
index 3de715384c1..398e80f422c 100644
--- a/arduino-core/src/processing/app/debug/Compiler.java
+++ b/arduino-core/src/processing/app/debug/Compiler.java
@@ -72,6 +72,7 @@ public class Compiler implements MessageConsumer {
private boolean saveHex;
private List objectFiles;
+ private List errors = new LinkedList();
private boolean sketchIsCompiled;
@@ -125,6 +126,7 @@ static public String build(SketchData data, String buildPath, File tempBuildFold
} catch (RunnerException e) {
// when the compile fails, take this opportunity to show
// any helpful info possible before throwing the exception
+ e.setErrors(compiler.getErrors());
compiler.adviseDuplicateLibraries();
throw e;
}
@@ -259,6 +261,8 @@ protected void cleanup(boolean force, File tempBuildFolder) {
// if the java runtime is holding onto any files in the build dir, we
// won't be able to delete them, so we need to force a gc here
System.gc();
+
+ errors.clear();
if (force) {
// delete the entire directory and all contents
@@ -869,28 +873,33 @@ public void message(String s) {
//msg = _("\nThe 'Keyboard' class is only supported on the Arduino Leonardo.\n\n");
}
- RunnerException e = null;
+ CompilerError e = null;
if (!sketchIsCompiled) {
// Place errors when compiling the sketch, but never while compiling libraries
// or the core. The user's sketch might contain the same filename!
- e = placeException(error, pieces[1], PApplet.parseInt(pieces[2]) - 1);
+ //e = placeException(error, pieces[1], PApplet.parseInt(pieces[2]) - 1);
+
+ e = new CompilerError(error, PApplet.parseInt(pieces[2]) - 1, pieces[1]);
+ errors.add(e);
+
}
// replace full file path with the name of the sketch tab (unless we're
// in verbose mode, in which case don't modify the compiler output)
if (e != null && !verbose) {
- SketchCode code = sketch.getCode(e.getCodeIndex());
+
+ SketchCode code = null;
+ for (SketchCode curr : sketch.getCodes()) {
+ if (e.getFileName().equals(curr.getFileName())) {
+ code = curr;
+ }
+ }
+
String fileName = (code.isExtension("ino") || code.isExtension("pde")) ? code.getPrettyName() : code.getFileName();
- int lineNum = e.getCodeLine() + 1;
+ int lineNum = e.getLine() + 1;
s = fileName + ":" + lineNum + ": error: " + error + msg;
}
- if (e != null) {
- if (exception == null || exception.getMessage().equals(e.getMessage())) {
- exception = e;
- exception.hideStackTrace();
- }
- }
}
if (s.contains("undefined reference to `SPIClass::begin()'") &&
@@ -1209,6 +1218,10 @@ public PreferencesMap getBuildPreferences() {
return prefs;
}
+ public List getErrors() {
+ return errors;
+ }
+
/**
* Build all the code for this sketch.
*
@@ -1335,27 +1348,6 @@ public void preprocess(String buildPath, PdePreprocessor preprocessor) throws Ru
private List importedDuplicateHeaders;
private List importedDuplicateLibraries;
- /**
- * Map an error from a set of processed .java files back to its location
- * in the actual sketch.
- * @param message The error message.
- * @param dotJavaFilename The .java file where the exception was found.
- * @param dotJavaLine Line number of the .java file for the exception (0-indexed!)
- * @return A RunnerException to be sent to the editor, or null if it wasn't
- * possible to place the exception to the sketch code.
- */
- public RunnerException placeException(String message,
- String dotJavaFilename,
- int dotJavaLine) {
- // Placing errors is simple, because we inserted #line directives
- // into the preprocessed source. The compiler gives us correct
- // the file name and line number. :-)
- for (SketchCode code : sketch.getCodes()) {
- if (dotJavaFilename.equals(code.getFileName())) {
- return new RunnerException(message, sketch.indexOfCode(code), dotJavaLine);
- }
- }
- return null;
- }
+
}
diff --git a/arduino-core/src/processing/app/debug/CompilerError.java b/arduino-core/src/processing/app/debug/CompilerError.java
new file mode 100755
index 00000000000..455f2c77e11
--- /dev/null
+++ b/arduino-core/src/processing/app/debug/CompilerError.java
@@ -0,0 +1,54 @@
+/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
+
+/*
+ Part of the Processing project - http://processing.org
+
+ Copyright (c) 2004-08 Ben Fry and Casey Reas
+ Copyright (c) 2001-04 Massachusetts Institute of Technology
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package processing.app.debug;
+
+/**
+ * An error with a line number attached that occurs during either compile time.
+ * @author Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ */
+public class CompilerError {
+
+ public CompilerError(String message, int line, String fileName) {
+ super();
+ this.message = message;
+ this.line = line;
+ this.fileName = fileName;
+ }
+
+ private int line;
+ private String message;
+ private String fileName;
+
+ public int getLine() {
+ return line;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public String getFileName() {
+ return fileName;
+ }
+
+}
\ No newline at end of file
diff --git a/arduino-core/src/processing/app/debug/RunnerException.java b/arduino-core/src/processing/app/debug/RunnerException.java
index 0a67d1e80ef..dce2a32ac6c 100644
--- a/arduino-core/src/processing/app/debug/RunnerException.java
+++ b/arduino-core/src/processing/app/debug/RunnerException.java
@@ -23,6 +23,8 @@
package processing.app.debug;
+import java.util.List;
+
/**
* An exception with a line number attached that occurs
@@ -31,9 +33,9 @@
@SuppressWarnings("serial")
public class RunnerException extends Exception {
protected String message;
- protected int codeIndex;
- protected int codeLine;
- protected int codeColumn;
+
+ protected List errors;
+
protected boolean showStackTrace;
@@ -42,27 +44,10 @@ public RunnerException(String message) {
}
public RunnerException(String message, boolean showStackTrace) {
- this(message, -1, -1, -1, showStackTrace);
- }
-
- public RunnerException(String message, int file, int line) {
- this(message, file, line, -1, true);
- }
-
-
- public RunnerException(String message, int file, int line, int column) {
- this(message, file, line, column, true);
- }
-
-
- public RunnerException(String message, int file, int line, int column,
- boolean showStackTrace) {
this.message = message;
- this.codeIndex = file;
- this.codeLine = line;
- this.codeColumn = column;
this.showStackTrace = showStackTrace;
}
+
public RunnerException(Exception e) {
@@ -83,47 +68,6 @@ public void setMessage(String message) {
this.message = message;
}
-
- public int getCodeIndex() {
- return codeIndex;
- }
-
-
- public void setCodeIndex(int index) {
- codeIndex = index;
- }
-
-
- public boolean hasCodeIndex() {
- return codeIndex != -1;
- }
-
-
- public int getCodeLine() {
- return codeLine;
- }
-
-
- public void setCodeLine(int line) {
- this.codeLine = line;
- }
-
-
- public boolean hasCodeLine() {
- return codeLine != -1;
- }
-
-
- public void setCodeColumn(int column) {
- this.codeColumn = column;
- }
-
-
- public int getCodeColumn() {
- return codeColumn;
- }
-
-
public void showStackTrace() {
showStackTrace = true;
}
@@ -152,6 +96,13 @@ static public final String massage(String msg) {
}
*/
+ public void setErrors( List errors ) {
+ this.errors = errors;
+ }
+
+ public List getErrors() {
+ return errors;
+ }
public void printStackTrace() {
if (showStackTrace) {
diff --git a/app/src/processing/app/helpers/ConsoleLogger.java b/arduino-core/src/processing/app/helpers/ConsoleLogger.java
old mode 100644
new mode 100755
similarity index 100%
rename from app/src/processing/app/helpers/ConsoleLogger.java
rename to arduino-core/src/processing/app/helpers/ConsoleLogger.java
diff --git a/arduino-core/src/processing/app/helpers/IPredicate.java b/arduino-core/src/processing/app/helpers/IPredicate.java
new file mode 100755
index 00000000000..3af53471d6e
--- /dev/null
+++ b/arduino-core/src/processing/app/helpers/IPredicate.java
@@ -0,0 +1,7 @@
+package processing.app.helpers;
+
+/**
+ * Interface to perform the filtering elements
+ * @author Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ */
+public interface IPredicate { boolean apply(T element); }
\ No newline at end of file
diff --git a/app/src/processing/app/helpers/LogFormatter.java b/arduino-core/src/processing/app/helpers/LogFormatter.java
old mode 100644
new mode 100755
similarity index 100%
rename from app/src/processing/app/helpers/LogFormatter.java
rename to arduino-core/src/processing/app/helpers/LogFormatter.java
diff --git a/arduino-core/src/processing/app/helpers/Predicate.java b/arduino-core/src/processing/app/helpers/Predicate.java
new file mode 100755
index 00000000000..b12c58d9ad8
--- /dev/null
+++ b/arduino-core/src/processing/app/helpers/Predicate.java
@@ -0,0 +1,47 @@
+package processing.app.helpers;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * Utility to filter elements based on predicates
+ * @author Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ */
+public class Predicate {
+
+ public static Collection filter(Collection extends T> list, IPredicate predicate) {
+ Collection result = new ArrayList();
+ return filter(list, predicate, result);
+ }
+
+ public static Collection filter(Collection extends T> list, IPredicate predicate, Collection target) {
+ for (T element : list) {
+ if (predicate.apply(element)) {
+ target.add(element);
+ }
+ }
+ return target;
+}
+
+ public static T select(Collection extends T> target, IPredicate predicate) {
+ T result = null;
+ for (T element : target) {
+ if (!predicate.apply(element))
+ continue;
+ result = element;
+ break;
+ }
+ return result;
+ }
+
+ public static T select(Collection extends T> target, IPredicate predicate, T defaultValue) {
+ T result = defaultValue;
+ for (T element : target) {
+ if (!predicate.apply(element))
+ continue;
+ result = element;
+ break;
+ }
+ return result;
+ }
+}
diff --git a/arduino-core/src/processing/app/helpers/StringUtils.java b/arduino-core/src/processing/app/helpers/StringUtils.java
index fb60df33020..a14f46f8804 100644
--- a/arduino-core/src/processing/app/helpers/StringUtils.java
+++ b/arduino-core/src/processing/app/helpers/StringUtils.java
@@ -40,4 +40,30 @@ public static String rtrim(String s) {
}
return s.substring(0, i + 1);
}
+
+ public static String findLastWord(String input){
+
+ int pos = -1;
+ for (int i = 0; i < input.length(); i++) {
+ if(Character.isUpperCase(input.charAt(i))){
+ pos = i;
+ }
+ }
+
+ if(pos > -1){
+ return input.substring(pos);
+ }else{
+ return null;
+ }
+
+ }
+
+ /**
+ * Make the first character of a String lower case
+ */
+ public static String uncapitalize(String input){
+ String firstLetter = input.substring(0,1).toLowerCase();
+ String restLetters = input.substring(1);
+ return firstLetter + restLetters;
+ }
}
diff --git a/arduino-core/src/processing/app/helpers/filefilters/OnlyFilesWithExtension.java b/arduino-core/src/processing/app/helpers/filefilters/OnlyFilesWithExtension.java
index c13adcbcfe8..eca40171306 100644
--- a/arduino-core/src/processing/app/helpers/filefilters/OnlyFilesWithExtension.java
+++ b/arduino-core/src/processing/app/helpers/filefilters/OnlyFilesWithExtension.java
@@ -23,16 +23,33 @@
import java.io.File;
import java.io.FilenameFilter;
+import java.util.Collection;
public class OnlyFilesWithExtension implements FilenameFilter {
String extensions[];
+ Collection ignoredFiles;
public OnlyFilesWithExtension(String... ext) {
this.extensions = ext;
}
+
+
+ public OnlyFilesWithExtension(Collection ignoredFiles, String... ext) {
+ super();
+ this.extensions = ext;
+ this.ignoredFiles = ignoredFiles;
+ }
+
public boolean accept(File dir, String name) {
+
+ if(ignoredFiles != null){
+ if(ignoredFiles.contains(name)){
+ return false;
+ }
+ }
+
for (String ext : extensions) {
if (name.endsWith(ext)) {
return true;
diff --git a/arduino-core/src/processing/app/packages/LibraryList.java b/arduino-core/src/processing/app/packages/LibraryList.java
index d4d504cea79..b9414dda3a1 100644
--- a/arduino-core/src/processing/app/packages/LibraryList.java
+++ b/arduino-core/src/processing/app/packages/LibraryList.java
@@ -30,13 +30,17 @@
import java.io.File;
import java.util.Collections;
+import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
+import java.util.Set;
import processing.app.helpers.FileUtils;
@SuppressWarnings("serial")
public class LibraryList extends LinkedList {
+
+ private Set listeners = new LinkedHashSet();
public LibraryList(LibraryList libs) {
super(libs);
@@ -87,5 +91,41 @@ public boolean hasLibrary(UserLibrary lib) {
if (l == lib) return true;
return false;
}
-}
+
+ @Override
+ public boolean add(UserLibrary l) {
+
+ if(l == null || l.getName() == null || l.getName().length() == 0) return false;
+
+ boolean add = super.add(l);
+ if(add){ // notify..
+ if(listeners != null) for (LibraryListener listener : listeners) { listener.onInsertLibrary(l);}
+ }
+
+ return add;
+ }
+
+ @Override
+ public boolean remove(Object l) {
+ boolean remove = super.remove(l);
+ if(remove){ // notify..
+ if(listeners != null) for (LibraryListener listener : listeners) { listener.onRemoveLibrary((UserLibrary)l);}
+ }
+ return remove;
+ }
+
+ @Override
+ public void clear() {
+ if(listeners != null) for (LibraryListener listener : listeners) { listener.onClearLibraryList();}
+ super.clear();
+ }
+ public boolean addListener(LibraryListener e) {
+ return listeners.add(e);
+ }
+
+ public boolean removeListener(LibraryListener e) {
+ return listeners.remove(e);
+ }
+
+}
diff --git a/arduino-core/src/processing/app/packages/LibraryListener.java b/arduino-core/src/processing/app/packages/LibraryListener.java
new file mode 100755
index 00000000000..9ec6df526cf
--- /dev/null
+++ b/arduino-core/src/processing/app/packages/LibraryListener.java
@@ -0,0 +1,15 @@
+package processing.app.packages;
+
+/**
+ * Interface to monitor sketck library changes
+ * @author Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ */
+public interface LibraryListener {
+
+ void onInsertLibrary(UserLibrary library);
+
+ void onRemoveLibrary(UserLibrary library);
+
+ void onClearLibraryList();
+
+}
diff --git a/arduino-core/src/processing/app/packages/SketchListener.java b/arduino-core/src/processing/app/packages/SketchListener.java
new file mode 100755
index 00000000000..5520167a722
--- /dev/null
+++ b/arduino-core/src/processing/app/packages/SketchListener.java
@@ -0,0 +1,18 @@
+package processing.app.packages;
+
+import processing.app.SketchCode;
+import processing.app.SketchData;
+
+public interface SketchListener {
+
+ public enum Event{
+ LOAD, INSERTED, SAVED
+ }
+
+ void onSketchLoad(SketchData sketch);
+
+ void onSketchInserted(SketchData sketch, SketchCode code);
+
+ void onSketchSaved(SketchData sketch, SketchCode code);
+
+}
diff --git a/build/build.xml b/build/build.xml
index f94e7975ca0..bcc97b601fd 100644
--- a/build/build.xml
+++ b/build/build.xml
@@ -74,6 +74,7 @@
+
@@ -112,11 +113,13 @@
+
+
diff --git a/build/linux/dist/arduino b/build/linux/dist/arduino
index 4e58bce3af1..04a7351beb2 100755
--- a/build/linux/dist/arduino
+++ b/build/linux/dist/arduino
@@ -33,4 +33,4 @@ if [ -x ./java/bin/java ]; then
JAVA=./java/bin/java
fi
-$JAVA -Dswing.defaultlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel $SPLASH processing.app.Base --curdir "$CURDIR" "$@"
+$JAVA -Dswing.defaultlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel $SPLASH ArduinoIDE --curdir "$CURDIR" "$@"
diff --git a/build/macosx/template.app/Contents/Info.plist b/build/macosx/template.app/Contents/Info.plist
index 5fa1337eb7a..a6d338d6009 100755
--- a/build/macosx/template.app/Contents/Info.plist
+++ b/build/macosx/template.app/Contents/Info.plist
@@ -97,7 +97,7 @@
- $JAVAROOT/antlr.jar:$JAVAROOT/apple.jar:$JAVAROOT/arduino-core.jar:$JAVAROOT/bcpg-jdk15on-152.jar:$JAVAROOT/bcprov-jdk15on-152.jar:$JAVAROOT/commons-codec-1.7.jar:$JAVAROOT/commons-compress-1.8.jar:$JAVAROOT/commons-exec-1.1.jar:$JAVAROOT/commons-httpclient-3.1.jar:$JAVAROOT/commons-lang3-3.3.2.jar:$JAVAROOT/commons-logging-1.0.4.jar:$JAVAROOT/ecj.jar:$JAVAROOT/guava-18.0.jar:$JAVAROOT/jackson-annotations-2.2.3.jar:$JAVAROOT/jackson-core-2.2.3.jar:$JAVAROOT/jackson-databind-2.2.3.jar:$JAVAROOT/jackson-module-mrbean-2.2.3.jar:$JAVAROOT/java-semver-0.8.0.jar:$JAVAROOT/jmdns-3.4.1.jar:$JAVAROOT/jsch-0.1.50.jar:$JAVAROOT/jssc-2.8.0.jar:$JAVAROOT/pde.jar:$JAVAROOT/quaqua.jar:$JAVAROOT/rsyntaxtextarea-2.5.6.1+arduino.jar
+ $JAVAROOT/antlr.jar:$JAVAROOT/apple.jar:$JAVAROOT/arduino-core.jar:$JAVAROOT/bcpg-jdk15on-152.jar:$JAVAROOT/bcprov-jdk15on-152.jar:$JAVAROOT/commons-codec-1.7.jar:$JAVAROOT/commons-compress-1.8.jar:$JAVAROOT/commons-exec-1.1.jar:$JAVAROOT/commons-httpclient-3.1.jar:$JAVAROOT/commons-lang3-3.3.2.jar:$JAVAROOT/commons-logging-1.0.4.jar:$JAVAROOT/ecj.jar:$JAVAROOT/guava-18.0.jar:$JAVAROOT/jackson-annotations-2.2.3.jar:$JAVAROOT/jackson-core-2.2.3.jar:$JAVAROOT/jackson-databind-2.2.3.jar:$JAVAROOT/jackson-module-mrbean-2.2.3.jar:$JAVAROOT/java-semver-0.8.0.jar:$JAVAROOT/jmdns-3.4.1.jar:$JAVAROOT/jsch-0.1.50.jar:$JAVAROOT/jssc-2.8.0.jar:$JAVAROOT/pde.jar:$JAVAROOT/quaqua.jar:$JAVAROOT/rsyntaxtextarea-2.5.6.1+arduino.jar:$JAVAROOT/rsyntax-autocomplete-2.6.0-SNAPSHOT.jar:$JAVAROOT/cplus-libparser-0.0.1.jar:$JAVAROOT/arduino-autocomplete.jar
JVMArchs
diff --git a/build/shared/lib/theme/syntax/eclipse.xml b/build/shared/lib/theme/syntax/eclipse.xml
new file mode 100644
index 00000000000..1196f801356
--- /dev/null
+++ b/build/shared/lib/theme/syntax/eclipse.xml
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/build/shared/lib/theme/syntax/idea.xml b/build/shared/lib/theme/syntax/idea.xml
new file mode 100644
index 00000000000..4ad96f44b7a
--- /dev/null
+++ b/build/shared/lib/theme/syntax/idea.xml
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/build/shared/lib/theme/syntax/visualstudio.xml b/build/shared/lib/theme/syntax/visualstudio.xml
new file mode 100644
index 00000000000..78692d9078e
--- /dev/null
+++ b/build/shared/lib/theme/syntax/visualstudio.xml
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/build/windows/launcher/config.xml b/build/windows/launcher/config.xml
index 3f2982a7922..993cdedce02 100644
--- a/build/windows/launcher/config.xml
+++ b/build/windows/launcher/config.xml
@@ -31,6 +31,9 @@
lib/jssc-2.8.0.jar
lib/pde.jar
lib/rsyntaxtextarea-2.5.6.1+arduino.jar
+ lib/rsyntax-autocomplete-2.6.0-SNAPSHOT.jar
+ lib/cplus-libparser-0.0.1.jar
+ lib/arduino-autocomplete.jar
java
diff --git a/build/windows/launcher/config_debug.xml b/build/windows/launcher/config_debug.xml
index bd40703320a..684e27cd6b4 100644
--- a/build/windows/launcher/config_debug.xml
+++ b/build/windows/launcher/config_debug.xml
@@ -31,6 +31,10 @@
lib/jssc-2.8.0.jar
lib/pde.jar
lib/rsyntaxtextarea-2.5.6.1+arduino.jar
+ lib/rsyntax-autocomplete-2.6.0-SNAPSHOT.jar
+ lib/cplus-libparser-0.0.1.jar
+ lib/arduino-autocomplete.jar
+
java
diff --git a/hardware/arduino/avr/cores/arduino/Arduino.h b/hardware/arduino/avr/cores/arduino/Arduino.h
index f1da68da7e7..1b38129c36d 100644
--- a/hardware/arduino/avr/cores/arduino/Arduino.h
+++ b/hardware/arduino/avr/cores/arduino/Arduino.h
@@ -122,12 +122,12 @@ void initVariant(void);
int atexit(void (*func)()) __attribute__((weak));
-void pinMode(uint8_t, uint8_t);
-void digitalWrite(uint8_t, uint8_t);
-int digitalRead(uint8_t);
-int analogRead(uint8_t);
+void pinMode(uint8_t pin, uint8_t mode);
+void digitalWrite(uint8_t pin, uint8_t value);
+int digitalRead(uint8_t pin);
+int analogRead(uint8_t pin);
void analogReference(uint8_t mode);
-void analogWrite(uint8_t, int);
+void analogWrite(uint8_t pin, int value);
unsigned long millis(void);
unsigned long micros(void);
@@ -239,10 +239,10 @@ void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0);
void noTone(uint8_t _pin);
// WMath prototypes
-long random(long);
-long random(long, long);
-void randomSeed(unsigned long);
-long map(long, long, long, long, long);
+long random(long max);
+long random(long min, long max);
+void randomSeed(unsigned long seed);
+long map(long value, long fromLow, long fromHigh, long toLow, long toHigh);
#endif