diff --git a/.classpath b/.classpath index 574e1c7f83d..19f199b2328 100644 --- a/.classpath +++ b/.classpath @@ -27,5 +27,8 @@ + + + diff --git a/app/.classpath b/app/.classpath index 27164be5b04..6919120e6f6 100644 --- a/app/.classpath +++ b/app/.classpath @@ -42,6 +42,7 @@ + @@ -54,5 +55,7 @@ + + diff --git a/app/build.xml b/app/build.xml index a2926990222..25e2397d365 100644 --- a/app/build.xml +++ b/app/build.xml @@ -135,6 +135,8 @@ - + + + diff --git a/app/lib/autocomplete-2.6.1.jar b/app/lib/autocomplete-2.6.1.jar new file mode 100755 index 00000000000..46964593fea Binary files /dev/null and b/app/lib/autocomplete-2.6.1.jar differ diff --git a/app/src/cc/arduino/UpdatableBoardsLibsFakeURLsHandler.java b/app/src/cc/arduino/UpdatableBoardsLibsFakeURLsHandler.java index 77694d925d3..3b9daddedcd 100644 --- a/app/src/cc/arduino/UpdatableBoardsLibsFakeURLsHandler.java +++ b/app/src/cc/arduino/UpdatableBoardsLibsFakeURLsHandler.java @@ -34,6 +34,10 @@ import javax.swing.event.HyperlinkEvent; import javax.swing.event.HyperlinkListener; import java.net.URL; +import java.net.URI; +import java.awt.Desktop; +import java.io.IOException; +import java.net.URISyntaxException; public class UpdatableBoardsLibsFakeURLsHandler implements HyperlinkListener { @@ -71,6 +75,18 @@ public void openBoardLibManager(URL url) { return; } + if(Desktop.isDesktopSupported()) + { + try { + Desktop.getDesktop().browse(url.toURI()); + return; + } catch (IOException e) { + throw new IllegalArgumentException(url.getHost() + " is invalid"); + } catch (URISyntaxException e) { + throw new IllegalArgumentException(url.getHost() + " is invalid"); + } + } + throw new IllegalArgumentException(url.getHost() + " is invalid"); } diff --git a/app/src/cc/arduino/autocomplete/ArduinoCompletionsList.java b/app/src/cc/arduino/autocomplete/ArduinoCompletionsList.java new file mode 100644 index 00000000000..a6d064b1948 --- /dev/null +++ b/app/src/cc/arduino/autocomplete/ArduinoCompletionsList.java @@ -0,0 +1,134 @@ +/* + * This file is part of Arduino. + * + * Copyright 2017 Arduino LLC (http://www.arduino.cc/) + * + * 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.autocomplete; + +import java.util.ArrayList; +import java.util.List; + +public class ArduinoCompletionsList extends ArrayList { +} + +class ArduinoCompletion { + ArduinoCompletionDetail completion; + String type; + String location; + List parameters; + + public ArduinoCompletionDetail getCompletion() { + return completion; + } + + public String getType() { + return type; + } + + public String getLocation() { + return location; + } + + public List getParameters() { + return parameters; + } +} + +class ArduinoParameter { + String name; + String type; + + public String getName() { + return name; + } + + public String getType() { + return type; + } +} + +class ArduinoCompletionDetail { + List chunks; + String brief; + + public List getChunks() { + return chunks; + } + + public String getBrief() { + return brief; + } + + public String getResultType() { + for (CompletionChunk c : chunks) { + if (c.res != null) + return c.res; + } + return null; + } + + public String getTypedText() { + for (CompletionChunk c : chunks) { + if (c.typedtext != null) + return c.typedtext; + } + return null; + } +} + +class CompletionChunk { + String typedtext; + String t; + String placeholder; + String res; + String info; + ArduinoCompletionDetail optional; + + public String getTypedtext() { + return typedtext; + } + + public String getT() { + return t; + } + + public String getPlaceholder() { + return placeholder; + } + + public String getRes() { + return res; + } + + public ArduinoCompletionDetail getOptional() { + return optional; + } + + public String getInfo() { + return info; + } +} \ No newline at end of file diff --git a/app/src/cc/arduino/autocomplete/BaseCCompletionProvider.java b/app/src/cc/arduino/autocomplete/BaseCCompletionProvider.java new file mode 100755 index 00000000000..3343ef16b39 --- /dev/null +++ b/app/src/cc/arduino/autocomplete/BaseCCompletionProvider.java @@ -0,0 +1,42 @@ +/* + * This file is part of Arduino. + * + * Copyright 2017 Arduino LLC (http://www.arduino.cc/) + * Ricardo JL Rufino (ricardo@criativasoft.com.br) + * + * 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.autocomplete; + +import org.fife.ui.autocomplete.DefaultCompletionProvider; + +public class BaseCCompletionProvider extends DefaultCompletionProvider { + + @Override + protected boolean isValidChar(char ch) { + return super.isValidChar(ch) || '.' == ch || '>' == ch || '-' == ch || '<' == ch || '#' == ch || ':' == ch /**|| getParameterListStart() == ch */; + } + +} diff --git a/app/src/cc/arduino/autocomplete/ClangCompletionProvider.java b/app/src/cc/arduino/autocomplete/ClangCompletionProvider.java new file mode 100644 index 00000000000..7ebe9fe524b --- /dev/null +++ b/app/src/cc/arduino/autocomplete/ClangCompletionProvider.java @@ -0,0 +1,199 @@ +/* + * This file is part of Arduino. + * + * Copyright 2017 Arduino LLC (http://www.arduino.cc/) + * + * 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.autocomplete; + +import java.util.ArrayList; +import java.util.List; + +import javax.swing.text.BadLocationException; +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.LanguageAwareCompletionProvider; +import org.fife.ui.autocomplete.ParameterizedCompletion.Parameter; +import org.fife.ui.autocomplete.TemplateCompletion; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import processing.app.Editor; +import processing.app.EditorTab; + +public class ClangCompletionProvider extends LanguageAwareCompletionProvider { + + private Editor editor; + private String completeCache; + private int completeCacheLine; + private int completeCacheColumn; + + public ClangCompletionProvider(Editor e, DefaultCompletionProvider cp) { + super(cp); + editor = e; + cp.setParameterizedCompletionParams('(', ", ", ')'); + } + + @Override + protected List getCompletionsImpl(JTextComponent textarea) { + + List res = new ArrayList<>(); + + // Retrieve current line and column + EditorTab tab = editor.getCurrentTab(); + int line, col; + try { + int pos = tab.getTextArea().getCaretPosition(); + line = tab.getTextArea().getLineOfOffset(pos); + col = pos - tab.getTextArea().getLineStartOffset(line); + line++; + col++; + } catch (BadLocationException e1) { + // Should never happen... + e1.printStackTrace(); + return res; + } + + try { + // Run codecompletion engine + String out = completeCache; + if (completeCacheLine != line || (completeCacheColumn != (col + 1)) && (completeCacheColumn != (col - 1))) { + out = editor.getSketchController() + .codeComplete(tab.getSketchFile(), line, col); + completeCache = out; + completeCacheLine = line; + } + completeCacheColumn = col; + + // Parse engine output and build code completions + ObjectMapper mapper = new ObjectMapper(); + ArduinoCompletionsList allCc; + try { + allCc = mapper.readValue(out, ArduinoCompletionsList.class); + } catch (JsonParseException e) { + System.err.println("Error parsing autocomplete output:"); + System.err.println(); + int begin = (int) e.getLocation().getCharOffset() - 100; + if (begin < 0) { + begin = 0; + } + int end = begin + 100; + if (end >= out.length()) { + System.err.println(out.substring(begin)); + } else { + System.err.println(out.substring(begin, end)); + } + System.err.println(); + e.printStackTrace(); + return res; + } + + String enteredText = getAlreadyEnteredText(textarea); + for (ArduinoCompletion cc : allCc) { + // Filter completions based on already entered text + if (!cc.getCompletion().getTypedText().startsWith(enteredText)) { + continue; + } + + Completion completion = createCompletionFromArduinoCompletion(cc); + res.add(completion); + } + return res; + } catch (Exception e) { + e.printStackTrace(); + return res; + } + } + + private Completion createCompletionFromArduinoCompletion(ArduinoCompletion cc) { + if (cc.type.equals("Function")) { + List params = new ArrayList<>(); + int i = 0; + String shortDesc = "("; + for (CompletionChunk chunk : cc.completion.chunks) { + if (chunk.placeholder != null) { + ArduinoParameter p = cc.parameters.get(i); + params.add(new Parameter(p.type, p.name)); + shortDesc += (p.name.equals("") ? p.type : p.name) + ", "; + i++; + } + } + int lastComma = shortDesc.lastIndexOf(","); + if (lastComma > 0) { + shortDesc = shortDesc.substring(0, lastComma); + } + shortDesc += ")"; + + FunctionCompletion compl = new FunctionCompletion(this, + cc.getCompletion().getTypedText(), + cc.getCompletion().getResultType()); + compl.setParams(params); + compl.setShortDescription(shortDesc + " : " + + cc.getCompletion().getResultType()); + return compl; + } else { + + String returnType = ""; + String typedText = null; + String template = ""; + String shortDesc = ""; + + for (CompletionChunk chunk : cc.completion.chunks) { + if (chunk.t != null) { + template += chunk.t; + shortDesc += chunk.t; + } + if (chunk.res != null) { + returnType = chunk.res; + } + if (chunk.typedtext != null) { + template += chunk.typedtext; + shortDesc += chunk.typedtext; + typedText = chunk.typedtext; + } + if (chunk.placeholder != null) { + String[] spl = chunk.placeholder.split(" "); + template += "${" + spl[spl.length - 1] + "}"; + shortDesc += spl[spl.length - 1]; + } + if (chunk.info != null) { + // System.out.println("INFO: "+chunk.info); + } + } + template += "${cursor}"; + System.out.println("TEMPLATE: " + template); + System.out.println("SHORT: " + shortDesc); + if (!returnType.isEmpty()) { + shortDesc += " : " + returnType; + } + return new TemplateCompletion(this, typedText, shortDesc, template); + } + } +} diff --git a/app/src/cc/arduino/autocomplete/CompletionType.java b/app/src/cc/arduino/autocomplete/CompletionType.java new file mode 100644 index 00000000000..01f9cc148b9 --- /dev/null +++ b/app/src/cc/arduino/autocomplete/CompletionType.java @@ -0,0 +1,34 @@ +/* + * This file is part of Arduino. + * + * Copyright 2017 Arduino LLC (www.arduino.cc) + * Ricardo JL Rufino (ricardo@criativasoft.com.br) + * + * 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.autocomplete; + +public enum CompletionType { + LIBRARY, CLASS, ENUM, STRUCT, LOCAL_VAR, STATIC_VAR, VARIABLE, FUNCTION, TEMPLATE, ERROR +} diff --git a/app/src/cc/arduino/autocomplete/CompletionsRenderer.java b/app/src/cc/arduino/autocomplete/CompletionsRenderer.java new file mode 100644 index 00000000000..d7a1a3917eb --- /dev/null +++ b/app/src/cc/arduino/autocomplete/CompletionsRenderer.java @@ -0,0 +1,172 @@ +/* + * This file is part of Arduino. + * + * Copyright 2017 Arduino LLC (www.arduino.cc) + * Ricardo JL Rufino (ricardo@criativasoft.com.br) + * + * 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.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 + */ +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) { + ShorthandCompletion v = (ShorthandCompletion) value; + text = v.getShortDescription(); + tokenType = CompletionType.TEMPLATE; + } else if (value instanceof FunctionCompletion) { + FunctionCompletion v = (FunctionCompletion) value; + text = font(v.getInputText(), LIGHT_BLUE) + " " + + font(v.getShortDescription(), GRAY); + tokenType = CompletionType.FUNCTION; + } else if (value instanceof BasicCompletion) { + BasicCompletion v = (BasicCompletion) value; + if (v.getShortDescription() != null) { + text = v.getShortDescription(); + } else { + text = v.getInputText(); + } + } else if (value instanceof TemplateCompletion) { + TemplateCompletion v = (TemplateCompletion) value; + text = font(v.getInputText(), LIGHT_BLUE) + " " + + font(v.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 + ""; + } + +} \ No newline at end of file diff --git a/app/src/cc/arduino/autocomplete/FakeCompletionProvider.java b/app/src/cc/arduino/autocomplete/FakeCompletionProvider.java new file mode 100755 index 00000000000..a7b69feffa1 --- /dev/null +++ b/app/src/cc/arduino/autocomplete/FakeCompletionProvider.java @@ -0,0 +1,57 @@ +/* + * This file is part of Arduino. + * + * Copyright 2017 Arduino LLC (http://www.arduino.cc/) + * + * 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.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 processing.app.syntax.SketchTextArea; + +public class FakeCompletionProvider extends BaseCCompletionProvider { + + @Override + protected List getCompletionsImpl(JTextComponent comp) { + List list = new LinkedList<>(); + + SketchTextArea area = (SketchTextArea) comp; + + list.add(new BasicCompletion(this, "Text: " + getAlreadyEnteredText(comp))); + list.add(new BasicCompletion(this, "Line: " + area.getCaretLineNumber())); + + return list; + } + + +} diff --git a/app/src/cc/arduino/autocomplete/SketchCompletionProvider.java b/app/src/cc/arduino/autocomplete/SketchCompletionProvider.java new file mode 100755 index 00000000000..3d33ce69c96 --- /dev/null +++ b/app/src/cc/arduino/autocomplete/SketchCompletionProvider.java @@ -0,0 +1,54 @@ +/* + * This file is part of Arduino. + * + * Copyright 2017 Arduino LLC (http://www.arduino.cc/) + * Ricardo JL Rufino (ricardo@criativasoft.com.br) + * + * 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.autocomplete; + +import org.fife.ui.autocomplete.CompletionProvider; +import org.fife.ui.autocomplete.LanguageAwareCompletionProvider; + +import processing.app.Sketch; +import processing.app.syntax.SketchTextArea; + +/** + * CompletionProvider for Arduino/CPP Language.
+ * Setup basic logic for completions using {@link LanguageAwareCompletionProvider}.
+ * Filtering and decision will appear in the autocomplete dialog by implementations of: {@link CompletionProvider}.
+ */ +public class SketchCompletionProvider extends LanguageAwareCompletionProvider { + + public SketchCompletionProvider(Sketch sketch, SketchTextArea textArea, CompletionProvider provider) { + + setDefaultCompletionProvider(provider); + // provider.setParameterChoicesProvider(new ParameterChoicesProvider(this)); + // provider.setParameterizedCompletionParams('(', ", ", ')'); + + } + +} \ No newline at end of file diff --git a/app/src/cc/arduino/autocomplete/icons/class.gif b/app/src/cc/arduino/autocomplete/icons/class.gif new file mode 100644 index 00000000000..e4c2a836f83 Binary files /dev/null and b/app/src/cc/arduino/autocomplete/icons/class.gif differ diff --git a/app/src/cc/arduino/autocomplete/icons/enum.gif b/app/src/cc/arduino/autocomplete/icons/enum.gif new file mode 100644 index 00000000000..15535f52f52 Binary files /dev/null and b/app/src/cc/arduino/autocomplete/icons/enum.gif differ diff --git a/app/src/cc/arduino/autocomplete/icons/error.gif b/app/src/cc/arduino/autocomplete/icons/error.gif new file mode 100644 index 00000000000..0bc60689c6d Binary files /dev/null and b/app/src/cc/arduino/autocomplete/icons/error.gif differ diff --git a/app/src/cc/arduino/autocomplete/icons/field_default_obj.gif b/app/src/cc/arduino/autocomplete/icons/field_default_obj.gif new file mode 100644 index 00000000000..6929d3d13f2 Binary files /dev/null and b/app/src/cc/arduino/autocomplete/icons/field_default_obj.gif differ diff --git a/app/src/cc/arduino/autocomplete/icons/field_public_obj.gif b/app/src/cc/arduino/autocomplete/icons/field_public_obj.gif new file mode 100644 index 00000000000..d4cb4254d92 Binary files /dev/null and b/app/src/cc/arduino/autocomplete/icons/field_public_obj.gif differ diff --git a/app/src/cc/arduino/autocomplete/icons/function.gif b/app/src/cc/arduino/autocomplete/icons/function.gif new file mode 100644 index 00000000000..7d24707ee82 Binary files /dev/null and b/app/src/cc/arduino/autocomplete/icons/function.gif differ diff --git a/app/src/cc/arduino/autocomplete/icons/function_static.gif b/app/src/cc/arduino/autocomplete/icons/function_static.gif new file mode 100644 index 00000000000..e02dc63568c Binary files /dev/null and b/app/src/cc/arduino/autocomplete/icons/function_static.gif differ diff --git a/app/src/cc/arduino/autocomplete/icons/int_obj.gif b/app/src/cc/arduino/autocomplete/icons/int_obj.gif new file mode 100644 index 00000000000..2ebc46e1d3b Binary files /dev/null and b/app/src/cc/arduino/autocomplete/icons/int_obj.gif differ diff --git a/app/src/cc/arduino/autocomplete/icons/jdoc_tag_obj.gif b/app/src/cc/arduino/autocomplete/icons/jdoc_tag_obj.gif new file mode 100644 index 00000000000..c43c5d51c51 Binary files /dev/null and b/app/src/cc/arduino/autocomplete/icons/jdoc_tag_obj.gif differ diff --git a/app/src/cc/arduino/autocomplete/icons/static_co.gif b/app/src/cc/arduino/autocomplete/icons/static_co.gif new file mode 100644 index 00000000000..6119fb446f4 Binary files /dev/null and b/app/src/cc/arduino/autocomplete/icons/static_co.gif differ diff --git a/app/src/cc/arduino/autocomplete/icons/template_obj.gif b/app/src/cc/arduino/autocomplete/icons/template_obj.gif new file mode 100644 index 00000000000..fdde5fbb95e Binary files /dev/null and b/app/src/cc/arduino/autocomplete/icons/template_obj.gif differ diff --git a/app/src/cc/arduino/autocomplete/icons/variable.gif b/app/src/cc/arduino/autocomplete/icons/variable.gif new file mode 100644 index 00000000000..f4a1ea15070 Binary files /dev/null and b/app/src/cc/arduino/autocomplete/icons/variable.gif differ diff --git a/app/src/cc/arduino/autocomplete/icons/variable_local.gif b/app/src/cc/arduino/autocomplete/icons/variable_local.gif new file mode 100644 index 00000000000..8adce9541f1 Binary files /dev/null and b/app/src/cc/arduino/autocomplete/icons/variable_local.gif differ diff --git a/app/src/cc/arduino/autocomplete/icons/variable_static.gif b/app/src/cc/arduino/autocomplete/icons/variable_static.gif new file mode 100644 index 00000000000..c63eb8506b0 Binary files /dev/null and b/app/src/cc/arduino/autocomplete/icons/variable_static.gif differ diff --git a/app/src/cc/arduino/view/NotificationPopup.java b/app/src/cc/arduino/view/NotificationPopup.java index 2de079c8525..2e6e294dc83 100644 --- a/app/src/cc/arduino/view/NotificationPopup.java +++ b/app/src/cc/arduino/view/NotificationPopup.java @@ -37,6 +37,13 @@ import java.awt.Image; import java.awt.Point; import java.awt.event.*; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.event.WindowFocusListener; import java.util.Timer; import java.util.TimerTask; @@ -51,6 +58,8 @@ import cc.arduino.Constants; import processing.app.PreferencesData; +import processing.app.Base; +import processing.app.Editor; import processing.app.Theme; import java.awt.event.KeyEvent; @@ -66,18 +75,20 @@ public interface OptionalButtonCallbacks { void onOptionalButton1Callback(); void onOptionalButton2Callback(); } + private Editor editor; - public NotificationPopup(Frame parent, HyperlinkListener hyperlinkListener, + public NotificationPopup(Editor parent, HyperlinkListener hyperlinkListener, String message) { this(parent, hyperlinkListener, message, true, null, null, null); + editor = parent; } - public NotificationPopup(Frame parent, HyperlinkListener hyperlinkListener, + public NotificationPopup(Editor parent, HyperlinkListener hyperlinkListener, String message, boolean _autoClose) { this(parent, hyperlinkListener, message, _autoClose, null, null, null); } - public NotificationPopup(Frame parent, HyperlinkListener hyperlinkListener, + public NotificationPopup(Editor parent, HyperlinkListener hyperlinkListener, String message, boolean _autoClose, OptionalButtonCallbacks listener, String button1Name, String button2Name) { super(parent, false); @@ -88,6 +99,7 @@ public NotificationPopup(Frame parent, HyperlinkListener hyperlinkListener, else { autoClose = false; } + editor = parent; optionalButtonCallbacks = listener; setLayout(new FlowLayout()); @@ -106,7 +118,9 @@ public NotificationPopup(Frame parent, HyperlinkListener hyperlinkListener, text.setEditable(false); text.setText(" " + message + " "); - text.addHyperlinkListener(hyperlinkListener); + if (hyperlinkListener != null) { + text.addHyperlinkListener(hyperlinkListener); + } add(text); if (button1Name != null) { @@ -271,4 +285,28 @@ public void run() { setModal(true); } } + + public void beginWhenFocused() { + if (editor.isFocused()) { + begin(); + return; + } + Base base = editor.getBase(); + + // If the IDE is not focused wait until it is focused again to + // display the notification, this avoids the annoying side effect + // to "steal" the focus from another application. + WindowFocusListener wfl = new WindowFocusListener() { + @Override + public void windowLostFocus(WindowEvent evt) { + } + + @Override + public void windowGainedFocus(WindowEvent evt) { + begin(); + base.getEditors().forEach(e -> e.removeWindowFocusListener(this)); + } + }; + base.getEditors().forEach(e -> e.addWindowFocusListener(wfl)); + } } diff --git a/app/src/cc/arduino/view/findreplace/FindReplace.java b/app/src/cc/arduino/view/findreplace/FindReplace.java index 03e7b10947d..988dc6f5a69 100644 --- a/app/src/cc/arduino/view/findreplace/FindReplace.java +++ b/app/src/cc/arduino/view/findreplace/FindReplace.java @@ -43,6 +43,7 @@ import java.util.HashMap; import java.util.Map; +import static java.awt.GraphicsDevice.WindowTranslucency.*; import static processing.app.I18n.tr; public class FindReplace extends javax.swing.JFrame { @@ -58,6 +59,7 @@ public class FindReplace extends javax.swing.JFrame { public FindReplace(Editor editor, Map state) { this.editor = editor; + isTranslucencySupported(); initComponents(); if (OSUtils.isMacOS()) { @@ -70,16 +72,28 @@ public FindReplace(Editor editor, Map state) { } Base.registerWindowCloseKeys(getRootPane(), e -> { + setAutoRequestFocus(true); setVisible(false); Base.FIND_DIALOG_STATE = findDialogState(); }); Base.setIcon(this); + editor.addWindowListener(new WindowAdapter() { + public void windowActivated(WindowEvent e) { + toFront(); + setAutoRequestFocus(false); + } + public void windowDeactivated(WindowEvent e) { + return; + } + }); + addWindowListener(new WindowAdapter() { public void windowActivated(WindowEvent e) { - findField.requestFocusInWindow(); - findField.selectAll(); + return; + } + public void windowDeactivated(WindowEvent e) { } }); @@ -89,10 +103,20 @@ public void windowActivated(WindowEvent e) { @Override public void setVisible(boolean b) { getRootPane().setDefaultButton(findButton); - + // means we are restoring the window visibility + setAutoRequestFocus(true); super.setVisible(b); } + private boolean useTranslucency; + + private void isTranslucencySupported() { + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice gd = ge.getDefaultScreenDevice(); + //If translucent windows aren't supported, exit. + useTranslucency = gd.isWindowTranslucencySupported(TRANSLUCENT); + } + private Map findDialogState() { Map state = new HashMap<>(); state.put(FIND_TEXT, findField.getText()); diff --git a/app/src/cc/arduino/view/preferences/Preferences.java b/app/src/cc/arduino/view/preferences/Preferences.java index 005d2f83e54..a92663687db 100644 --- a/app/src/cc/arduino/view/preferences/Preferences.java +++ b/app/src/cc/arduino/view/preferences/Preferences.java @@ -130,6 +130,7 @@ private void initComponents() { checkboxesContainer = new javax.swing.JPanel(); displayLineNumbersBox = new javax.swing.JCheckBox(); enableCodeFoldingBox = new javax.swing.JCheckBox(); + enableBookmarks = new javax.swing.JCheckBox(); verifyUploadBox = new javax.swing.JCheckBox(); externalEditorBox = new javax.swing.JCheckBox(); checkUpdatesBox = new javax.swing.JCheckBox(); @@ -255,6 +256,9 @@ public void mouseEntered(java.awt.event.MouseEvent evt) { enableCodeFoldingBox.setText(tr("Enable Code Folding")); checkboxesContainer.add(enableCodeFoldingBox); + enableBookmarks.setText(tr("Enable Bookmarks")); + checkboxesContainer.add(enableBookmarks); + verifyUploadBox.setText(tr("Verify code after upload")); checkboxesContainer.add(verifyUploadBox); @@ -725,6 +729,7 @@ private void autoScaleCheckBoxItemStateChanged(java.awt.event.ItemEvent evt) {// private javax.swing.JLabel comboWarningsLabel; private javax.swing.JCheckBox displayLineNumbersBox; private javax.swing.JCheckBox enableCodeFoldingBox; + private javax.swing.JCheckBox enableBookmarks; private javax.swing.JButton extendedAdditionalUrlFieldWindow; private javax.swing.JCheckBox externalEditorBox; private javax.swing.JTextField fontSizeField; @@ -823,6 +828,8 @@ private void savePreferencesData() { PreferencesData.setBoolean("editor.code_folding", enableCodeFoldingBox.isSelected()); + PreferencesData.setBoolean("editor.bookmarks", enableBookmarks.isSelected()); + PreferencesData.setBoolean("upload.verify", verifyUploadBox.isSelected()); PreferencesData.setBoolean("editor.save_on_verify", saveVerifyUploadBox.isSelected()); @@ -897,6 +904,8 @@ private void showPreferencesData() { enableCodeFoldingBox.setSelected(PreferencesData.getBoolean("editor.code_folding")); + enableBookmarks.setSelected(PreferencesData.getBoolean("editor.bookmarks")); + verifyUploadBox.setSelected(PreferencesData.getBoolean("upload.verify")); externalEditorBox.setSelected(PreferencesData.getBoolean("editor.external")); diff --git a/app/src/processing/app/AbstractTextMonitor.java b/app/src/processing/app/AbstractTextMonitor.java index 00eabb20649..ffc244a8214 100644 --- a/app/src/processing/app/AbstractTextMonitor.java +++ b/app/src/processing/app/AbstractTextMonitor.java @@ -32,6 +32,9 @@ import javax.swing.border.EmptyBorder; import javax.swing.text.DefaultCaret; import javax.swing.text.DefaultEditorKit; +import javax.swing.event.UndoableEditListener; +import javax.swing.text.AbstractDocument; +import javax.swing.text.Document; import cc.arduino.packages.BoardPort; @@ -40,7 +43,9 @@ public abstract class AbstractTextMonitor extends AbstractMonitor { protected JLabel noLineEndingAlert; protected TextAreaFIFO textArea; + protected HTMLTextAreaFIFO htmlTextArea; protected JScrollPane scrollPane; + protected JScrollPane htmlScrollPane; protected JTextField textField; protected JButton sendButton; protected JButton clearButton; @@ -48,6 +53,10 @@ public abstract class AbstractTextMonitor extends AbstractMonitor { protected JCheckBox addTimeStampBox; protected JComboBox lineEndings; protected JComboBox serialRates; + protected Container mainPane; + private long lastMessage; + private javax.swing.Timer updateTimer; + private boolean htmlView = true; public AbstractTextMonitor(BoardPort boardPort) { super(boardPort); @@ -69,6 +78,7 @@ public synchronized void addKeyListener(KeyListener l) { @Override protected void onCreateWindow(Container mainPane) { + this.mainPane = mainPane; mainPane.setLayout(new BorderLayout()); textArea = new TextAreaFIFO(8_000_000); @@ -76,14 +86,89 @@ protected void onCreateWindow(Container mainPane) { textArea.setColumns(40); textArea.setEditable(false); + htmlTextArea = new HTMLTextAreaFIFO(8000000); + htmlTextArea.setEditable(false); + htmlTextArea.setOpaque(false); + // don't automatically update the caret. that way we can manually decide // whether or not to do so based on the autoscroll checkbox. ((DefaultCaret) textArea.getCaret()).setUpdatePolicy(DefaultCaret.NEVER_UPDATE); + ((DefaultCaret) htmlTextArea.getCaret()).setUpdatePolicy(DefaultCaret.NEVER_UPDATE); + + Document doc = textArea.getDocument(); + if (doc instanceof AbstractDocument) + { + UndoableEditListener[] undoListeners = + ( (AbstractDocument) doc).getUndoableEditListeners(); + if (undoListeners.length > 0) + { + for (UndoableEditListener undoListener : undoListeners) + { + doc.removeUndoableEditListener(undoListener); + } + } + } + + doc = htmlTextArea.getDocument(); + if (doc instanceof AbstractDocument) + { + UndoableEditListener[] undoListeners = + ( (AbstractDocument) doc).getUndoableEditListeners(); + if (undoListeners.length > 0) + { + for (UndoableEditListener undoListener : undoListeners) + { + doc.removeUndoableEditListener(undoListener); + } + } + } scrollPane = new JScrollPane(textArea); + scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); + htmlScrollPane = new JScrollPane(htmlTextArea); + htmlScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); + + ActionListener checkIfSteady = new ActionListener() { + public void actionPerformed(ActionEvent evt) { + if (System.currentTimeMillis() - lastMessage > 200) { + if (htmlView == false && textArea.getLength() < 1000) { + + htmlTextArea.setText(""); + boolean res = htmlTextArea.append(textArea.getText()); + if (res) { + htmlView = true; + mainPane.remove(scrollPane); + if (textArea.getCaretPosition() > htmlTextArea.getDocument().getLength()) { + htmlTextArea.setCaretPosition(htmlTextArea.getDocument().getLength()); + } else { + htmlTextArea.setCaretPosition(textArea.getCaretPosition()); + } + mainPane.add(htmlScrollPane, BorderLayout.CENTER); + scrollPane.setVisible(false); + mainPane.validate(); + mainPane.repaint(); + } + } + } else { + if (htmlView == true) { + htmlView = false; + mainPane.remove(htmlScrollPane); + mainPane.add(scrollPane, BorderLayout.CENTER); + scrollPane.setVisible(true); + mainPane.validate(); + mainPane.repaint(); + } + } + } + }; + + updateTimer = new javax.swing.Timer(33, checkIfSteady); mainPane.add(scrollPane, BorderLayout.CENTER); + htmlTextArea.setVisible(true); + htmlScrollPane.setVisible(true); + JPanel upperPane = new JPanel(); upperPane.setLayout(new BoxLayout(upperPane, BoxLayout.X_AXIS)); upperPane.setBorder(new EmptyBorder(4, 4, 4, 4)); @@ -168,6 +253,8 @@ public void windowGainedFocus(WindowEvent e) { applyPreferences(); mainPane.add(pane, BorderLayout.SOUTH); + + updateTimer.start(); } @Override @@ -190,9 +277,21 @@ protected void onEnableWindow(boolean enable) { textArea.setBackground(new Color(238, 238, 238)); } textArea.invalidate(); + + clearButton.setEnabled(enable); + htmlTextArea.setEnabled(enable); scrollPane.setEnabled(enable); + htmlScrollPane.setEnabled(enable); textField.setEnabled(enable); sendButton.setEnabled(enable); + + autoscrollBox.setEnabled(enable); + addTimeStampBox.setEnabled(enable); + lineEndings.setEnabled(enable); + serialRates.setEnabled(enable); + if (enable == false) { + htmlTextArea.setText(""); + } } public void onSendCommand(ActionListener listener) { @@ -210,6 +309,7 @@ public void onSerialRateChange(ActionListener listener) { @Override public void message(String msg) { + lastMessage = System.currentTimeMillis(); SwingUtilities.invokeLater(() -> updateTextArea(msg)); } diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 7af728fdd49..a1a10c385ab 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -116,6 +116,13 @@ public class Base { List editors = Collections.synchronizedList(new ArrayList()); Editor activeEditor; + private static JMenu boardMenu; + private static ButtonGroup boardsButtonGroup; + private static ButtonGroup recentBoardsButtonGroup; + private static Map buttonGroupsMap; + private static List menuItemsToClickAfterStartup; + private static MenuScroller boardMenuScroller; + // these menus are shared so that the board and serial port selections // are the same for all windows (since the board and serial port that are // actually used are determined by the preferences, which are shared) @@ -563,6 +570,36 @@ protected boolean restoreSketches() throws Exception { return (opened > 0); } + protected boolean restoreRecentlyUsedBoards() throws Exception { + // Iterate through all sketches that were open last time p5 was running. + // If !windowPositionValid, then ignore the coordinates found for each. + + // Save the sketch path and window placement for each open sketch + int count = PreferencesData.getInteger("last.recent_boards.count"); + int opened = 0; + for (int i = count - 1; i >= 0; i--) { + String fqbn = PreferencesData.get("last.recent_board" + i + ".fqbn"); + if (fqbn == null) { + continue; + } + //selectTargetBoard(new TargetBoard()); + } + return count != 0; + } + + /** + * Store list of sketches that are currently open. + * Called when the application is quitting and documents are still open. + */ + protected void storeRecentlyUsedBoards() { + int i = 0; + for (TargetBoard board : BaseNoGui.getRecentlyUsedBoards()) { + PreferencesData.set("last.recent_board" + i + ".fqbn", board.getFQBN()); + i++; + } + PreferencesData.setInteger("last.recent_boards.count", BaseNoGui.getRecentlyUsedBoards().size()); + } + /** * Store screen dimensions on last close */ @@ -1342,7 +1379,66 @@ public void rebuildExamplesMenu(JMenu menu) { private static String priorPlatformFolder; private static boolean newLibraryImported; - public void onBoardOrPortChange() { + public void selectTargetBoard(TargetBoard targetBoard) { + for (int i = 0; i < boardMenu.getItemCount(); i++) { + JMenuItem menuItem = boardMenu.getItem(i); + if (!(menuItem instanceof JRadioButtonMenuItem)) { + continue; + } + + JRadioButtonMenuItem radioButtonMenuItem = ((JRadioButtonMenuItem) menuItem); + if (targetBoard.getName().equals(radioButtonMenuItem.getText())) { + radioButtonMenuItem.setSelected(true); + break; + } + } + + BaseNoGui.selectBoard(targetBoard); + filterVisibilityOfSubsequentBoardMenus(boardsCustomMenus, targetBoard, 1); + + onBoardOrPortChange(); + rebuildImportMenu(Editor.importMenu); + rebuildExamplesMenu(Editor.examplesMenu); + rebuildProgrammerMenu(); + + try { + rebuildRecentBoardsMenu(); + } catch (Exception e) { + // fail silently + } + } + + public void rebuildRecentBoardsMenu() throws Exception { + + Enumeration btns = recentBoardsButtonGroup.getElements(); + while (btns.hasMoreElements()) { + AbstractButton x = btns.nextElement(); + if (x.isSelected()) { + return; + } + } + btns = recentBoardsButtonGroup.getElements(); + while (btns.hasMoreElements()) { + AbstractButton x = btns.nextElement(); + boardMenu.remove(x); + } + int index = 0; + for (TargetBoard board : BaseNoGui.getRecentlyUsedBoards()) { + JMenuItem item = createBoardMenusAndCustomMenus(boardsCustomMenus, menuItemsToClickAfterStartup, + buttonGroupsMap, + board, board.getContainerPlatform(), board.getContainerPlatform().getContainerPackage()); + boardMenu.insert(item, 3); + item.setAccelerator(KeyStroke.getKeyStroke('1' + index, + Toolkit.getDefaultToolkit().getMenuShortcutKeyMask() | + ActionEvent.SHIFT_MASK)); + recentBoardsButtonGroup.add(item); + boardsButtonGroup.add(item); + index ++; + } + boardMenuScroller.setTopFixedCount(3 + index); + } + + public synchronized void onBoardOrPortChange() { BaseNoGui.onBoardOrPortChange(); // reload keywords when package/platform changes @@ -1435,9 +1531,10 @@ public void rebuildBoardsMenu() throws Exception { boardsCustomMenus = new LinkedList<>(); // The first custom menu is the "Board" selection submenu - JMenu boardMenu = new JMenu(tr("Board")); + boardMenu = new JMenu(tr("Board")); boardMenu.putClientProperty("removeOnWindowDeactivation", true); - MenuScroller.setScrollerFor(boardMenu).setTopFixedCount(1); + boardMenuScroller = MenuScroller.setScrollerFor(boardMenu); + boardMenuScroller.setTopFixedCount(1); boardMenu.add(new JMenuItem(new AbstractAction(tr("Boards Manager...")) { public void actionPerformed(ActionEvent actionevent) { @@ -1477,10 +1574,19 @@ public void actionPerformed(ActionEvent actionevent) { } } - List menuItemsToClickAfterStartup = new LinkedList<>(); + List _menuItemsToClickAfterStartup = new LinkedList<>(); + boardsButtonGroup = new ButtonGroup(); + recentBoardsButtonGroup = new ButtonGroup(); + buttonGroupsMap = new HashMap<>(); - ButtonGroup boardsButtonGroup = new ButtonGroup(); - Map buttonGroupsMap = new HashMap<>(); + boolean hasRecentBoardsMenu = (PreferencesData.getInteger("editor.recent_boards.size", 4) != 0); + + if (hasRecentBoardsMenu) { + JMenuItem recentLabel = new JMenuItem(tr("Recently used boards")); + recentLabel.setEnabled(false); + boardMenu.add(recentLabel); + boardMenu.add(new JSeparator()); + } List platformMenus = new ArrayList<>(); @@ -1502,7 +1608,7 @@ public void actionPerformed(ActionEvent actionevent) { for (TargetBoard board : targetPlatform.getBoards().values()) { if (board.getPreferences().get("hide") != null) continue; - JMenuItem item = createBoardMenusAndCustomMenus(boardsCustomMenus, menuItemsToClickAfterStartup, + JMenuItem item = createBoardMenusAndCustomMenus(boardsCustomMenus, _menuItemsToClickAfterStartup, buttonGroupsMap, board, targetPlatform, targetPackage); platformBoardsMenu.add(item); @@ -1537,14 +1643,16 @@ public void actionPerformed(ActionEvent actionevent) { // If there is no current board yet (first startup, or selected // board no longer defined), select first available board. - if (menuItemsToClickAfterStartup.isEmpty()) { - menuItemsToClickAfterStartup.add(firstBoardItem); + if (_menuItemsToClickAfterStartup.isEmpty()) { + _menuItemsToClickAfterStartup.add(firstBoardItem); } - for (JMenuItem menuItemToClick : menuItemsToClickAfterStartup) { + for (JMenuItem menuItemToClick : _menuItemsToClickAfterStartup) { menuItemToClick.setSelected(true); menuItemToClick.getAction().actionPerformed(new ActionEvent(this, -1, "")); } + + menuItemsToClickAfterStartup = _menuItemsToClickAfterStartup; } private String getPlatformUniqueId(TargetPlatform platform) { @@ -1568,13 +1676,20 @@ private JRadioButtonMenuItem createBoardMenusAndCustomMenus( @SuppressWarnings("serial") Action action = new AbstractAction(board.getName()) { public void actionPerformed(ActionEvent actionevent) { - BaseNoGui.selectBoard((TargetBoard) getValue("b")); - filterVisibilityOfSubsequentBoardMenus(boardsCustomMenus, (TargetBoard) getValue("b"), 1); - - onBoardOrPortChange(); - rebuildImportMenu(Editor.importMenu); - rebuildExamplesMenu(Editor.examplesMenu); - rebuildProgrammerMenu(); + new Thread() + { + public void run() { + if (activeEditor != null && activeEditor.isUploading()) { + // block until isUploading becomes false, but aboid blocking the UI + while (activeEditor.isUploading()) { + try { + Thread.sleep(100); + } catch (InterruptedException e) {} + } + } + selectTargetBoard((TargetBoard) getValue("b")); + } + }.start(); } }; action.putValue("b", board); @@ -1590,6 +1705,9 @@ public void actionPerformed(ActionEvent actionevent) { for (final String menuId : customMenus.keySet()) { String title = customMenus.get(menuId); JMenu menu = getBoardCustomMenu(tr(title), getPlatformUniqueId(targetPlatform)); + if (menu == null) { + continue; + } if (board.hasMenu(menuId)) { PreferencesMap boardCustomMenu = board.getMenuLabels(menuId); @@ -1665,7 +1783,7 @@ private JMenu getBoardCustomMenu(String label, String platformUniqueId) throws E return menu; } } - throw new Exception("Custom menu not found!"); + return null; } public List getProgrammerMenus() { diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java index 2ec29c498cb..d6cca158b73 100644 --- a/app/src/processing/app/Editor.java +++ b/app/src/processing/app/Editor.java @@ -110,6 +110,15 @@ import processing.app.tools.MenuScroller; import processing.app.tools.Tool; +import processing.app.tools.WatchDir; +import static java.nio.file.StandardWatchEventKinds.*; +import java.nio.file.WatchService; +import java.nio.file.WatchKey; +import java.nio.file.WatchEvent; +import java.nio.file.FileSystems; +import java.nio.file.Path; +import java.io.File; + /** * Main editor panel for the Processing Development Environment. */ @@ -124,6 +133,7 @@ public class Editor extends JFrame implements RunnerListener { private final Box upper; private ArrayList tabs = new ArrayList<>(); private int currentTabIndex = -1; + private static boolean watcherDisable = false; private static class ShouldSaveIfModified implements Predicate { @@ -238,6 +248,8 @@ public boolean test(SketchController controller) { private Runnable timeoutUploadHandler; private Map internalToolCache = new HashMap(); + protected Thread watcher = null; + protected Runnable task = null; public Editor(Base ibase, File file, int[] storedLocation, int[] defaultLocation, Platform platform) throws Exception { super("Arduino"); @@ -263,12 +275,20 @@ public void windowClosing(WindowEvent e) { // When bringing a window to front, let the Base know addWindowListener(new WindowAdapter() { public void windowActivated(WindowEvent e) { + if (watcher != null) { + watcher.interrupt(); + watcher = null; + } base.handleActivated(Editor.this); } // added for 1.0.5 // http://dev.processing.org/bugs/show_bug.cgi?id=1260 public void windowDeactivated(WindowEvent e) { + if (watcher == null) { + watcher = new Thread(task); + watcher.start(); + } List toolsMenuItemsToRemove = new LinkedList<>(); for (Component menuItem : toolsMenu.getMenuComponents()) { if (menuItem instanceof JComponent) { @@ -383,6 +403,9 @@ public void windowDeactivated(WindowEvent e) { EditorConsole.setCurrentEditorConsole(console); } + public Base getBase() { + return base; + } /** * Handles files dragged & dropped from the desktop and into the editor @@ -1542,7 +1565,7 @@ public void reorderTabs() { * the given file. * @throws IOException */ - protected void addTab(SketchFile file, String contents) throws IOException { + public synchronized void addTab(SketchFile file, String contents) throws IOException { EditorTab tab = new EditorTab(this, file, contents); tab.getTextArea().getDocument() .addDocumentListener(new DocumentTextChangeListener( @@ -1551,9 +1574,12 @@ protected void addTab(SketchFile file, String contents) throws IOException { reorderTabs(); } - protected void removeTab(SketchFile file) throws IOException { + public synchronized void removeTab(SketchFile file) throws IOException { int index = findTabIndex(file); tabs.remove(index); + if (index == currentTabIndex) { + currentTabIndex = currentTabIndex -1; + } } // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @@ -1829,6 +1855,25 @@ protected boolean handleOpenInternal(File sketchFile) { // Disable untitled setting from previous document, if any untitled = false; + if (watcherDisable == true) { + return true; + } + + // Add FS watcher for current Editor instance + Path dir = file.toPath().getParent(); + + Editor instance = this; + + task = new Runnable() { + public void run() { + try { + new WatchDir(dir, true).processEvents(instance); + } catch (IOException x) { + watcherDisable = true; + } + } + }; + // opening was successful return true; } diff --git a/app/src/processing/app/EditorHeader.java b/app/src/processing/app/EditorHeader.java index 25c09a8dfaa..5c9380a8f17 100644 --- a/app/src/processing/app/EditorHeader.java +++ b/app/src/processing/app/EditorHeader.java @@ -27,6 +27,9 @@ import processing.app.helpers.OSUtils; import processing.app.helpers.SimpleAction; import processing.app.tools.MenuScroller; +import java.awt.event.MouseWheelListener; +import java.awt.event.MouseWheelEvent; + import static processing.app.I18n.tr; import java.awt.*; @@ -189,6 +192,25 @@ public void mousePressed(MouseEvent e) { } } }); + + this.addMouseWheelListener(new MouseAdapter() { + public void mouseWheelMoved(MouseWheelEvent e) { + if (e.getWheelRotation() > 0) { + int index = editor.getCurrentTabIndex() + 1; + if (index >= (editor.getTabs().size())) { + index = 0; + } + editor.selectTab(index); + } else { + int index = editor.getCurrentTabIndex() - 1; + if (index < 0) { + index = editor.getTabs().size() -1 ; + } + editor.selectTab(index); + } + repaint(); + } + }); } @@ -201,16 +223,7 @@ public void paintComponent(Graphics screen) { Dimension size = getSize(); if ((size.width != sizeW) || (size.height != sizeH)) { // component has been resized - - if ((size.width > imageW) || (size.height > imageH)) { - // nix the image and recreate, it's too small - offscreen = null; - - } else { - // who cares, just resize - sizeW = size.width; - sizeH = size.height; - } + offscreen = null; } if (offscreen == null) { @@ -233,6 +246,8 @@ public void paintComponent(Graphics screen) { g.setColor(backgroundColor); g.fillRect(0, 0, imageW, imageH); + imageW = sizeW - 30 - menuButtons[0].getWidth(this); + List tabs = editor.getTabs(); int codeCount = tabs.size(); @@ -243,6 +258,10 @@ public void paintComponent(Graphics screen) { int x = scale(6); // offset from left edge of the component int i = 0; + int selected = 0; + int size_selected = 0; + + // dry run, get the correct offset for (EditorTab tab : tabs) { SketchFile file = tab.getSketchFile(); String filename = file.getPrettyName(); @@ -253,6 +272,78 @@ public void paintComponent(Graphics screen) { int textWidth = (int) font.getStringBounds(text, g.getFontRenderContext()).getWidth(); + int pieceCount = 2 + (textWidth / PIECE_WIDTH); + + int state = (i == editor.getCurrentTabIndex()) ? SELECTED : UNSELECTED; + int x_initial = x; + x += PIECE_WIDTH; + + tabLeft[i] = x; + x += PIECE_WIDTH * pieceCount; + tabRight[i] = x; + + x += PIECE_WIDTH - 1; // overlap by 1 pixel + + if (state == SELECTED) { + selected = i; + size_selected = x - x_initial; + } + + i++; + } + + int non_selected_tab_size = 0; + + if (x > imageW) { + // find scaling factor + non_selected_tab_size = (imageW - size_selected)/(codeCount -1); + } + + if ((non_selected_tab_size > 0) && (size_selected > (3 * non_selected_tab_size))) { + // limit the maximum size of tab in case of crowded tabs + size_selected = 3 * non_selected_tab_size; + } + + i = 0; + x = scale(6); // offset from left edge of the component + + for (EditorTab tab : tabs) { + SketchFile file = tab.getSketchFile(); + String filename = file.getPrettyName(); + + // if modified, add the li'l glyph next to the name + String text = " " + filename + (file.isModified() ? " \u00A7" : " "); + + int textWidth = (int) + font.getStringBounds(text, g.getFontRenderContext()).getWidth(); + + if (non_selected_tab_size > 0) { + // find a suitable title + while (textWidth + 3 * PIECE_WIDTH > ((i != selected) ? non_selected_tab_size: size_selected) && filename.length() > 2) { + filename = filename.substring(0, filename.length()-1); + text = " " + filename + ".." + (file.isModified() ? " \u00A7" : " "); + textWidth = (int)font.getStringBounds(text, g.getFontRenderContext()).getWidth(); + } + } + + int current_tab_size = non_selected_tab_size; + if (i == selected) { + current_tab_size = size_selected; + } + + int padding = x + current_tab_size; + + if (padding > imageW) { + if (i <= selected) { + // create another surface to overlay g + g.setColor(backgroundColor); + g.fillRect(0, 0, sizeW, imageH); + x = scale(6); + } else { + break; + } + } + int pieceCount = 2 + (textWidth / PIECE_WIDTH); int pieceWidth = pieceCount * PIECE_WIDTH; @@ -276,6 +367,7 @@ public void paintComponent(Graphics screen) { g.drawImage(pieces[state][RIGHT], x, 0, null); x += PIECE_WIDTH - 1; // overlap by 1 pixel + i++; } diff --git a/app/src/processing/app/EditorTab.java b/app/src/processing/app/EditorTab.java index 5e8f3e4bfcf..696979ac775 100644 --- a/app/src/processing/app/EditorTab.java +++ b/app/src/processing/app/EditorTab.java @@ -28,18 +28,30 @@ import java.awt.BorderLayout; import java.awt.Font; +import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseWheelListener; +import java.awt.event.MouseWheelEvent; + import java.io.IOException; import javax.swing.Action; import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.InputMap; +import javax.swing.JComponent; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JPopupMenu; +import javax.swing.KeyStroke; +import javax.swing.SwingUtilities; import javax.swing.ToolTipManager; +import javax.swing.UIManager; import javax.swing.border.MatteBorder; import javax.swing.event.PopupMenuEvent; import javax.swing.event.PopupMenuListener; @@ -49,20 +61,43 @@ import javax.swing.text.DefaultCaret; import javax.swing.text.Document; +import static java.nio.file.StandardWatchEventKinds.*; +import java.nio.file.WatchService; +import java.util.ArrayList; +import java.util.List; +import java.nio.file.WatchKey; +import java.nio.file.WatchEvent; +import java.nio.file.FileSystems; +import java.nio.file.Path; +import java.io.File; + import org.apache.commons.lang3.StringUtils; +import org.fife.ui.autocomplete.AutoCompletion; +import org.fife.ui.autocomplete.DefaultCompletionProvider; import org.fife.ui.rsyntaxtextarea.RSyntaxDocument; +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; import org.fife.ui.rsyntaxtextarea.RSyntaxTextAreaEditorKit; import org.fife.ui.rsyntaxtextarea.RSyntaxUtilities; import org.fife.ui.rtextarea.Gutter; +import org.fife.ui.rtextarea.GutterIconInfo; +import org.fife.ui.rtextarea.RTADefaultInputMap; +import org.fife.ui.rtextarea.RTextArea; +import org.fife.ui.rtextarea.RTextAreaEditorKit; import org.fife.ui.rtextarea.RTextScrollPane; +import org.fife.ui.rtextarea.RecordableTextAction; import cc.arduino.UpdatableBoardsLibsFakeURLsHandler; +import cc.arduino.autocomplete.ClangCompletionProvider; +import cc.arduino.autocomplete.CompletionType; +import cc.arduino.autocomplete.CompletionsRenderer; import processing.app.helpers.DocumentTextChangeListener; +import processing.app.helpers.PreferencesMap; import processing.app.syntax.ArduinoTokenMakerFactory; import processing.app.syntax.PdeKeywords; import processing.app.syntax.SketchTextArea; import processing.app.syntax.SketchTextAreaEditorKit; import processing.app.tools.DiscourseFormat; +import processing.app.tools.WatchDir; /** * Single tab, editing a single file, in the main window. @@ -110,6 +145,19 @@ public EditorTab(Editor editor, SketchFile file, String contents) applyPreferences(); add(scrollPane, BorderLayout.CENTER); editor.base.addEditorFontResizeMouseWheelListener(textarea); +// SketchCompletionProvider completionProvider = new SketchCompletionProvider( +// editor.getSketch(), textarea, new ClangCompletionProvider(editor)); + + DefaultCompletionProvider cp = new DefaultCompletionProvider(); + AutoCompletion ac = new AutoCompletion(new ClangCompletionProvider(editor, cp)); + ac.setAutoActivationEnabled(true); + ac.setShowDescWindow(false); + ac.setAutoCompleteSingleChoices(true); + ac.setParameterAssistanceEnabled(true); + ac.setListCellRenderer(new CompletionsRenderer()); + // ac.setParamChoicesRenderer(new CompletionsRenderer()); + // ac.setListCellRenderer(new CompletionsRenderer()); + ac.install(textarea); } private RSyntaxDocument createDocument(String contents) { @@ -127,6 +175,8 @@ private RSyntaxDocument createDocument(String contents) { return document; } + public static final String rtaNextBookmarkAction = "RTA.NextBookmarkAction"; + private RTextScrollPane createScrollPane(SketchTextArea textArea) throws IOException { RTextScrollPane scrollPane = new RTextScrollPane(textArea, true); scrollPane.setBorder(new MatteBorder(0, 6, 0, 0, Theme.getColor("editor.bgcolor"))); @@ -135,13 +185,118 @@ private RTextScrollPane createScrollPane(SketchTextArea textArea) throws IOExcep scrollPane.setIconRowHeaderEnabled(false); Gutter gutter = scrollPane.getGutter(); - gutter.setBookmarkingEnabled(false); - //gutter.setBookmarkIcon(CompletionsRenderer.getIcon(CompletionType.TEMPLATE)); + + if (PreferencesData.getBoolean("editor.bookmarks")) { + gutter.setBookmarkingEnabled(true); + gutter.setBookmarkIcon(CompletionsRenderer.getIcon(CompletionType.FUNCTION)); + InputMap map = SwingUtilities.getUIInputMap(textArea, JComponent.WHEN_FOCUSED); + NextBookmarkAction action = new NextBookmarkAction(rtaNextBookmarkAction); + map.put(KeyStroke.getKeyStroke(KeyEvent.VK_F3, 0), action); + SwingUtilities.replaceUIInputMap(textArea,JComponent.WHEN_FOCUSED,map); + } + gutter.setIconRowHeaderInheritsGutterBackground(true); return scrollPane; } + public class GutterIconInfoTabs { + GutterIconInfo bookmark; + SketchFile file; + RTextArea textArea; + + public String toString( ) { + return "File:" + file.getFileName() + " -- Line:" + bookmark.getMarkedOffset(); + } + } + + /** + * Action that moves the caret to the next bookmark. + */ + public class NextBookmarkAction extends RecordableTextAction { + + public NextBookmarkAction(String name) { + super(name); + } + + @Override + public void actionPerformedImpl(ActionEvent e, RTextArea textArea) { + + Gutter gutter = RSyntaxUtilities.getGutter(textArea); + + List bookmarks = new ArrayList(); + + try { + + for (EditorTab tab : editor.getTabs()) { + gutter = RSyntaxUtilities.getGutter(tab.getTextArea()); + + if (gutter!=null) { + GutterIconInfo[] tabBookmarks = gutter.getBookmarks(); + for (GutterIconInfo element : tabBookmarks) { + GutterIconInfoTabs bookmark = new GutterIconInfoTabs(); + bookmark.file = tab.getSketchFile(); + bookmark.bookmark = element; + bookmark.textArea = tab.getTextArea(); + bookmarks.add(bookmark); + } + } + } + + if (bookmarks.size()==0) { + UIManager.getLookAndFeel(). + provideErrorFeedback(textArea); + return; + } + + GutterIconInfoTabs moveTo = null; + int curLine = textArea.getCaretLineNumber(); + + for (int i=0; icurLine) || (curTabIndex < bookmarkTabIndex)) { + moveTo = bookmarks.get(i); + break; + } + } + if (moveTo==null) { // Loop back to beginning + moveTo = bookmarks.get(0); + } + + editor.selectTab(editor.findTabIndex(moveTo.file)); + + int offs = moveTo.bookmark.getMarkedOffset(); + if (moveTo.textArea instanceof RSyntaxTextArea) { + RSyntaxTextArea rsta = (RSyntaxTextArea)moveTo.textArea; + if (rsta.isCodeFoldingEnabled()) { + rsta.getFoldManager(). + ensureOffsetNotInClosedFold(offs); + } + } + int line = moveTo.textArea.getLineOfOffset(offs); + offs = moveTo.textArea.getLineStartOffset(line); + moveTo.textArea.setCaretPosition(offs); + + } catch (BadLocationException ble) { // Never happens + UIManager.getLookAndFeel(). + provideErrorFeedback(textArea); + ble.printStackTrace(); + } + } + + @Override + public String getMacroID() { + return getName(); + } + } + private SketchTextArea createTextArea(RSyntaxDocument document) throws IOException { final SketchTextArea textArea = new SketchTextArea(document, editor.base.getPdeKeywords()); @@ -486,7 +641,11 @@ public void setSelection(int start, int stop) { public int getScrollPosition() { return scrollPane.getVerticalScrollBar().getValue(); } - + + public RTextScrollPane getScrollPane() { + return scrollPane; + } + public void setScrollPosition(int pos) { scrollPane.getVerticalScrollBar().setValue(pos); } diff --git a/app/src/processing/app/HTMLTextAreaFIFO.java b/app/src/processing/app/HTMLTextAreaFIFO.java new file mode 100644 index 00000000000..0aa3aabfe9c --- /dev/null +++ b/app/src/processing/app/HTMLTextAreaFIFO.java @@ -0,0 +1,160 @@ +/* + Copyright (c) 2014 Paul Stoffregen + + 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 +*/ + +// adapted from https://community.oracle.com/thread/1479784 + +package processing.app; + +import java.io.IOException; +import java.net.URL; +import java.awt.Desktop; +import java.net.URLEncoder; + +import java.util.*; +import java.util.regex.*; + +import javax.swing.text.html.HTMLDocument; +import javax.swing.JEditorPane; +import javax.swing.JTextPane; +import javax.swing.SwingUtilities; +import javax.swing.event.HyperlinkEvent; +import javax.swing.event.HyperlinkListener; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.text.BadLocationException; +import javax.swing.text.html.HTMLEditorKit; + +import cc.arduino.UpdatableBoardsLibsFakeURLsHandler; + +public class HTMLTextAreaFIFO extends JTextPane implements DocumentListener { + private int maxChars; + private int trimMaxChars; + + private int updateCount; // limit how often we trim the document + + private boolean doTrim; + private final HTMLEditorKit kit; + + public HTMLTextAreaFIFO(int max) { + maxChars = max; + trimMaxChars = max / 2; + updateCount = 0; + doTrim = true; + setContentType("text/html"); + getDocument().addDocumentListener(this); + setText(""); + kit = new HTMLEditorKit(); + this.addHyperlinkListener(new UpdatableBoardsLibsFakeURLsHandler(Base.INSTANCE)); + } + + public void insertUpdate(DocumentEvent e) { + } + + public void removeUpdate(DocumentEvent e) { + } + + public void changedUpdate(DocumentEvent e) { + } + + public void trimDocument() { + int len = 0; + len = getDocument().getLength(); + if (len > trimMaxChars) { + int n = len - trimMaxChars; + //System.out.println("trimDocument: remove " + n + " chars"); + try { + getDocument().remove(0, n); + } catch (BadLocationException ble) { + } + } + } + + private static List extractUrls(String input) { + List result = new ArrayList(); + + Pattern pattern = Pattern.compile( + "(http|ftp|https)://([^\\s]+)"); + + Matcher matcher = pattern.matcher(input); + while (matcher.find()) { + result.add(matcher.group()); + } + + return result; + } + + static public final String WITH_DELIMITER = "((?<=%1$s)|(?=%1$s))"; + + public boolean append(String s) { + boolean htmlFound = false; + try { + HTMLDocument doc = (HTMLDocument) getDocument(); + + String strings[] = s.split(String.format(WITH_DELIMITER, "\\r?\\n")); + + for (int l = 0; l < strings.length; l++) { + String str = strings[l]; + List urls = extractUrls(str); + + if (urls.size() > 0) { + + for (int i = 0; i < urls.size(); i++) { + if (!((urls.get(i)).contains(""))) { + str = str.replace(urls.get(i), "" + urls.get(i) + ""); + } + } + + kit.insertHTML(doc, doc.getLength(), str, 0, 0, null); + htmlFound = true; + } else { + doc.insertString(doc.getLength(), str, null); + } + } + } catch(BadLocationException exc) { + exc.printStackTrace(); + } catch(IOException exc) { + exc.printStackTrace(); + } + + if (++updateCount > 150 && doTrim) { + updateCount = 0; + SwingUtilities.invokeLater(new Runnable() { + public void run() { + trimDocument(); + } + }); + } + return htmlFound; + } + + public void appendNoTrim(String s) { + int free = maxChars - getDocument().getLength(); + if (free <= 0) + return; + if (s.length() > free) + append(s.substring(0, free)); + else + append(s); + doTrim = false; + } + + public void appendTrim(String str) { + append(str); + doTrim = true; + } +} diff --git a/app/src/processing/app/NewBoardListener.java b/app/src/processing/app/NewBoardListener.java index 7e0fe61d708..423262df215 100644 --- a/app/src/processing/app/NewBoardListener.java +++ b/app/src/processing/app/NewBoardListener.java @@ -73,34 +73,11 @@ public void checkForNewBoardAttached() { } SwingUtilities.invokeLater(() -> { - ed = base.getActiveEditor(); NotificationPopup notificationPopup = new NotificationPopup(ed, new UpdatableBoardsLibsFakeURLsHandler(base), newBoardManagerLink, false); - if (ed.isFocused()) { - notificationPopup.begin(); - return; - } - - // If the IDE is not focused wait until it is focused again to - // display the notification, this avoids the annoying side effect - // to "steal" the focus from another application. - WindowFocusListener wfl = new WindowFocusListener() { - @Override - public void windowLostFocus(WindowEvent evt) { - } - - @Override - public void windowGainedFocus(WindowEvent evt) { - notificationPopup.begin(); - for (Editor e : base.getEditors()) - e.removeWindowFocusListener(this); - } - }; - - for (Editor e : base.getEditors()) - e.addWindowFocusListener(wfl); + notificationPopup.beginWhenFocused(); }); } } diff --git a/app/src/processing/app/SketchController.java b/app/src/processing/app/SketchController.java index ce9e468cc68..f7d708dab3f 100644 --- a/app/src/processing/app/SketchController.java +++ b/app/src/processing/app/SketchController.java @@ -26,7 +26,9 @@ import cc.arduino.Compiler; import cc.arduino.CompilerProgressListener; import cc.arduino.UploaderUtils; +import cc.arduino.builder.ArduinoBuilder; import cc.arduino.packages.Uploader; +import cc.arduino.view.NotificationPopup; import processing.app.debug.RunnerException; import processing.app.forms.PasswordAuthorizationDialog; import processing.app.helpers.FileUtils; @@ -37,6 +39,8 @@ import javax.swing.*; import java.awt.*; +import java.awt.event.WindowEvent; +import java.awt.event.WindowFocusListener; import java.io.File; import java.io.IOException; import java.nio.file.Files; @@ -58,10 +62,18 @@ public class SketchController { private final Editor editor; private final Sketch sketch; + private final ArduinoBuilder builder; public SketchController(Editor _editor, Sketch _sketch) { + ArduinoBuilder _builder = null; + try { + _builder = new ArduinoBuilder(); + } catch (IOException e) { + e.printStackTrace(); + } editor = _editor; sketch = _sketch; + builder = _builder; } private boolean renamingCode; @@ -680,6 +692,66 @@ private File saveSketchInTempFolder() throws IOException { return Paths.get(tempFolder.getAbsolutePath(), sketch.getPrimaryFile().getFileName()).toFile(); } + /** + * Preprocess sketch and obtain code-completions. + * + * @return null if compilation failed, main class name if not + */ + public String codeComplete(SketchFile file, int line, int col) throws RunnerException, PreferencesMapException, IOException { + // run the preprocessor + for (CompilerProgressListener progressListener : editor.status.getCompilerProgressListeners()){ + progressListener.progress(20); + } + + ensureExistence(); + + boolean deleteTemp = false; + File pathToSketch = sketch.getPrimaryFile().getFile(); + File requestedFile = file.getFile(); + if (sketch.isModified()) { + // If any files are modified, make a copy of the sketch with the changes + // saved, so arduino-builder will see the modifications. + pathToSketch = saveSketchInTempFolder(); + // This takes into account when the sketch is copied into a temporary folder + requestedFile = new File(pathToSketch.getParent(), requestedFile.getName()); + deleteTemp = true; + } + + try { + return builder.codeComplete(BaseNoGui.getTargetBoard(), pathToSketch, requestedFile, line, col); + //return new Compiler(pathToSketch, sketch).codeComplete(editor.status.getCompilerProgressListeners(), requestedFile, line, col); + } catch (Exception x) { + + // Try getting some more useful information about the error; + // Launch the same command in non-daemon mode, overriding verbosity to + // print the actual call + // TODO: override verbosity + try { + // Gather command line and preprocesor output + String out = new Compiler(pathToSketch, sketch) + .codeComplete(editor.status.getCompilerProgressListeners(), + requestedFile, line, col); + System.out.println("autocomplete failure output:\n" + out); + + SwingUtilities.invokeLater(() -> { + NotificationPopup notificationPopup = new NotificationPopup(editor, + null, tr("Code complete is not available. Try increasing ulimit."), + true); + notificationPopup.beginWhenFocused(); + }); + + return ""; + } catch (Exception e) { + // Ignore + return ""; + } + } finally { + // Make sure we clean up any temporary sketch copy + if (deleteTemp) + FileUtils.recursiveDelete(pathToSketch.getParentFile()); + } + } + /** * Handle export to applet. */ diff --git a/app/src/processing/app/TextAreaFIFO.java b/app/src/processing/app/TextAreaFIFO.java index abf953dfd93..7ee3f653b0d 100644 --- a/app/src/processing/app/TextAreaFIFO.java +++ b/app/src/processing/app/TextAreaFIFO.java @@ -72,6 +72,10 @@ public void trimDocument() { } } + public int getLength() { + return getDocument().getLength(); + } + public void appendNoTrim(String s) { int free = maxChars - getDocument().getLength(); if (free <= 0) diff --git a/app/src/processing/app/syntax/SketchTextArea.java b/app/src/processing/app/syntax/SketchTextArea.java index ce74a3f1f8f..7801f1a0c54 100644 --- a/app/src/processing/app/syntax/SketchTextArea.java +++ b/app/src/processing/app/syntax/SketchTextArea.java @@ -66,6 +66,49 @@ import processing.app.Base; import processing.app.PreferencesData; + +import javax.swing.event.EventListenerList; +import javax.swing.event.HyperlinkEvent; +import javax.swing.event.HyperlinkListener; +import javax.swing.text.BadLocationException; +import javax.swing.text.Segment; +import java.awt.*; +import java.awt.event.MouseEvent; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Map; +import java.util.logging.Logger; + +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.Segment; + +import org.apache.commons.compress.utils.IOUtils; +import org.fife.ui.autocomplete.AutoCompletion; +import org.fife.ui.autocomplete.CompletionProvider; +import org.fife.ui.rsyntaxtextarea.LinkGenerator; +import org.fife.ui.rsyntaxtextarea.LinkGeneratorResult; +import org.fife.ui.rsyntaxtextarea.RSyntaxDocument; +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.rtextarea.RTextArea; +import org.fife.ui.rtextarea.RTextAreaUI; + +import cc.arduino.autocomplete.SketchCompletionProvider; +import processing.app.Base; +import processing.app.BaseNoGui; +import processing.app.PreferencesData; +import processing.app.Sketch; import processing.app.helpers.OSUtils; /** @@ -74,12 +117,13 @@ * @author Ricardo JL Rufino (ricardo@criativasoft.com.br) * @since 1.6.4 */ +@SuppressWarnings("unused") public class SketchTextArea extends RSyntaxTextArea { private final static Logger LOG = Logger.getLogger(SketchTextArea.class.getName()); private PdeKeywords pdeKeywords; - + public SketchTextArea(RSyntaxDocument document, PdeKeywords pdeKeywords) throws IOException { super(document); this.pdeKeywords = pdeKeywords; @@ -91,7 +135,7 @@ public void setKeywords(PdeKeywords keywords) { pdeKeywords = keywords; setLinkGenerator(new DocLinkGenerator(pdeKeywords)); } - + private void installFeatures() throws IOException { setTheme(PreferencesData.get("editor.syntax_theme", "default")); diff --git a/app/src/processing/app/tools/WatchDir.java b/app/src/processing/app/tools/WatchDir.java new file mode 100644 index 00000000000..8346c04014e --- /dev/null +++ b/app/src/processing/app/tools/WatchDir.java @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package processing.app.tools; + +import java.nio.file.*; +import static java.nio.file.StandardWatchEventKinds.*; +import static java.nio.file.LinkOption.*; +import java.nio.file.attribute.*; +import java.io.*; +import java.util.*; +import processing.app.Editor; +import processing.app.EditorTab; +import processing.app.Sketch; +import processing.app.SketchFile; +import processing.app.helpers.FileUtils; + +/** + * Example to watch a directory (or tree) for changes to files. + */ + +public class WatchDir { + + private final WatchService watcher; + private final Map keys; + private final boolean recursive; + private boolean trace = false; + + @SuppressWarnings("unchecked") + static WatchEvent cast(WatchEvent event) { + return (WatchEvent)event; + } + + /** + * Register the given directory with the WatchService + */ + private void register(Path dir) throws IOException { + WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY); + if (trace) { + Path prev = keys.get(key); + if (prev == null) { + } else { + if (!dir.equals(prev)) { + } + } + } + keys.put(key, dir); + } + + /** + * Register the given directory, and all its sub-directories, with the + * WatchService. + */ + private void registerAll(final Path start) throws IOException { + // register directory and sub-directories + Files.walkFileTree(start, new SimpleFileVisitor() { + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) + throws IOException + { + register(dir); + return FileVisitResult.CONTINUE; + } + }); + } + + /** + * Creates a WatchService and registers the given directory + */ + public WatchDir(Path dir, boolean recursive) throws IOException { + this.watcher = FileSystems.getDefault().newWatchService(); + this.keys = new HashMap(); + this.recursive = recursive; + + if (recursive) { + registerAll(dir); + } else { + register(dir); + } + + // enable trace after initial registration + this.trace = true; + } + + /** + * Process all events for keys queued to the watcher + */ + public void processEvents(Editor editor) { + for (;;) { + + // wait for key to be signalled + WatchKey key; + try { + key = watcher.take(); + } catch (InterruptedException x) { + return; + } + + Path dir = keys.get(key); + if (dir == null) { + continue; + } + + for (WatchEvent event: key.pollEvents()) { + WatchEvent.Kind kind = event.kind(); + + // TBD - provide example of how OVERFLOW event is handled + if (kind == OVERFLOW) { + continue; + } + + // Context for directory entry event is the file name of entry + WatchEvent ev = cast(event); + Path name = ev.context(); + Path child = dir.resolve(name); + + // reload the tab content + if (kind == ENTRY_CREATE) { + try { + String filename = name.toString(); + FileUtils.SplitFile split = FileUtils.splitFilename(filename); + if (Sketch.EXTENSIONS.contains(split.extension.toLowerCase())) { + SketchFile sketch = editor.getSketch().addFile(filename); + editor.addTab(sketch, null); + } + } catch (Exception e) { + return; + } + } else if (kind == ENTRY_DELETE) { + try { + Thread.sleep(100); + int index = editor.getSketch().findFileIndex(child.toAbsolutePath().toFile()); + editor.removeTab(editor.getSketch().getFile(index)); + } catch (Exception e1) { + // Totally fine, if the sleep gets interrupted it means that + // the action was executed in the UI, not externally + return; + } + } + editor.getTabs().forEach(tab -> { + if (!tab.isModified()) { + tab.reload(); + } + }); + // if directory is created, and watching recursively, then + // register it and its sub-directories + if (recursive && (kind == ENTRY_CREATE)) { + try { + if (Files.isDirectory(child, NOFOLLOW_LINKS)) { + registerAll(child); + } + } catch (IOException x) { + // ignore to keep sample readbale + } + } + } + + // reset key and remove from set if directory no longer accessible + boolean valid = key.reset(); + if (!valid) { + keys.remove(key); + + // all directories are inaccessible + if (keys.isEmpty()) { + break; + } + } + } + } +} diff --git a/arduino-core/.classpath b/arduino-core/.classpath index b4f9733f8dd..1eac2a29fb1 100644 --- a/arduino-core/.classpath +++ b/arduino-core/.classpath @@ -26,5 +26,20 @@ + + + + + + + + + + + + + + + diff --git a/arduino-core/lib/grpc-auth-1.6.1.jar b/arduino-core/lib/grpc-auth-1.6.1.jar new file mode 100644 index 00000000000..e39f6bc348c Binary files /dev/null and b/arduino-core/lib/grpc-auth-1.6.1.jar differ diff --git a/arduino-core/lib/grpc-context-1.6.1.jar b/arduino-core/lib/grpc-context-1.6.1.jar new file mode 100644 index 00000000000..f6660b4b15e Binary files /dev/null and b/arduino-core/lib/grpc-context-1.6.1.jar differ diff --git a/arduino-core/lib/grpc-core-1.6.1.jar b/arduino-core/lib/grpc-core-1.6.1.jar new file mode 100644 index 00000000000..397af7e95b2 Binary files /dev/null and b/arduino-core/lib/grpc-core-1.6.1.jar differ diff --git a/arduino-core/lib/grpc-grpclb-1.6.1.jar b/arduino-core/lib/grpc-grpclb-1.6.1.jar new file mode 100644 index 00000000000..08d4bbb6bf4 Binary files /dev/null and b/arduino-core/lib/grpc-grpclb-1.6.1.jar differ diff --git a/arduino-core/lib/grpc-netty-1.6.1.jar b/arduino-core/lib/grpc-netty-1.6.1.jar new file mode 100644 index 00000000000..2ed7a4513a2 Binary files /dev/null and b/arduino-core/lib/grpc-netty-1.6.1.jar differ diff --git a/arduino-core/lib/grpc-okhttp-1.6.1.jar b/arduino-core/lib/grpc-okhttp-1.6.1.jar new file mode 100644 index 00000000000..35eb1b5de89 Binary files /dev/null and b/arduino-core/lib/grpc-okhttp-1.6.1.jar differ diff --git a/arduino-core/lib/grpc-protobuf-1.6.1.jar b/arduino-core/lib/grpc-protobuf-1.6.1.jar new file mode 100644 index 00000000000..ef1fe6bbd5a Binary files /dev/null and b/arduino-core/lib/grpc-protobuf-1.6.1.jar differ diff --git a/arduino-core/lib/grpc-protobuf-lite-1.6.1.jar b/arduino-core/lib/grpc-protobuf-lite-1.6.1.jar new file mode 100644 index 00000000000..af60539aaa2 Binary files /dev/null and b/arduino-core/lib/grpc-protobuf-lite-1.6.1.jar differ diff --git a/arduino-core/lib/grpc-protobuf-nano-1.6.1.jar b/arduino-core/lib/grpc-protobuf-nano-1.6.1.jar new file mode 100644 index 00000000000..35680794b63 Binary files /dev/null and b/arduino-core/lib/grpc-protobuf-nano-1.6.1.jar differ diff --git a/arduino-core/lib/grpc-services-1.6.1.jar b/arduino-core/lib/grpc-services-1.6.1.jar new file mode 100644 index 00000000000..6f6592d422f Binary files /dev/null and b/arduino-core/lib/grpc-services-1.6.1.jar differ diff --git a/arduino-core/lib/grpc-stub-1.6.1.jar b/arduino-core/lib/grpc-stub-1.6.1.jar new file mode 100644 index 00000000000..b33e4d7c851 Binary files /dev/null and b/arduino-core/lib/grpc-stub-1.6.1.jar differ diff --git a/arduino-core/lib/guava-19.0.jar b/arduino-core/lib/guava-19.0.jar new file mode 100644 index 00000000000..b175ca867fe Binary files /dev/null and b/arduino-core/lib/guava-19.0.jar differ diff --git a/arduino-core/lib/instrumentation-api-0.4.3.jar b/arduino-core/lib/instrumentation-api-0.4.3.jar new file mode 100644 index 00000000000..fd8baee04f2 Binary files /dev/null and b/arduino-core/lib/instrumentation-api-0.4.3.jar differ diff --git a/arduino-core/lib/jsr305-3.0.2.jar b/arduino-core/lib/jsr305-3.0.2.jar new file mode 100644 index 00000000000..59222d9ca5e Binary files /dev/null and b/arduino-core/lib/jsr305-3.0.2.jar differ diff --git a/arduino-core/lib/netty-all-4.1.15.Final.jar b/arduino-core/lib/netty-all-4.1.15.Final.jar new file mode 100644 index 00000000000..d9f565a5257 Binary files /dev/null and b/arduino-core/lib/netty-all-4.1.15.Final.jar differ diff --git a/arduino-core/lib/protobuf-java-3.4.0.jar b/arduino-core/lib/protobuf-java-3.4.0.jar new file mode 100644 index 00000000000..ec27fae9b0d Binary files /dev/null and b/arduino-core/lib/protobuf-java-3.4.0.jar differ diff --git a/arduino-core/src/cc/arduino/Compiler.java b/arduino-core/src/cc/arduino/Compiler.java index c2c5b0ff624..a3aa833576d 100644 --- a/arduino-core/src/cc/arduino/Compiler.java +++ b/arduino-core/src/cc/arduino/Compiler.java @@ -55,7 +55,6 @@ import java.util.Map; import java.util.regex.Pattern; import java.util.stream.Collectors; -import java.util.stream.Stream; import static processing.app.I18n.tr; @@ -125,7 +124,7 @@ public class Compiler implements MessageConsumer { } enum BuilderAction { - COMPILE("-compile"), DUMP_PREFS("-dump-prefs"); + COMPILE("-compile"), DUMP_PREFS("-dump-prefs"), CODE_COMPLETE("-code-complete-at"); final String value; @@ -143,6 +142,10 @@ enum BuilderAction { private final boolean verbose; private RunnerException exception; + private File codeCompleteFile; + private int codeCompleteLine; + private int codeCompleteCol; + public Compiler(Sketch data) { this(data.getPrimaryFile().getFile(), data); } @@ -168,16 +171,14 @@ public String build(List progListeners, boolean export throw new RunnerException("Board is not selected"); } - TargetPlatform platform = board.getContainerPlatform(); - TargetPackage aPackage = platform.getContainerPackage(); String vidpid = VIDPID(); - PreferencesMap prefs = loadPreferences(board, platform, aPackage, vidpid); + PreferencesMap prefs = loadPreferences(board, vidpid); MessageConsumerOutputStream out = new MessageConsumerOutputStream(new ProgressAwareMessageConsumer(new I18NAwareMessageConsumer(System.out, System.err), progListeners), "\n"); MessageConsumerOutputStream err = new MessageConsumerOutputStream(new I18NAwareMessageConsumer(System.err, Compiler.this), "\n"); - callArduinoBuilder(board, platform, aPackage, vidpid, BuilderAction.COMPILE, out, err); + callArduinoBuilder(board, vidpid, BuilderAction.COMPILE, out, err); out.flush(); err.flush(); @@ -193,6 +194,32 @@ public String build(List progListeners, boolean export return sketch.getPrimaryFile().getFileName(); } + public String codeComplete(ArrayList progListeners, File file, int line, int col) throws RunnerException, PreferencesMapException, IOException { + this.buildPath = sketch.getBuildPath().getAbsolutePath(); + this.buildCache = BaseNoGui.getCachePath(); + + TargetBoard board = BaseNoGui.getTargetBoard(); + if (board == null) { + throw new RunnerException("Board is not selected"); + } + + String vidpid = VIDPID(); + + ByteArrayOutputStream completions = new ByteArrayOutputStream(); + MessageConsumerOutputStream out = new MessageConsumerOutputStream(new ProgressAwareMessageConsumer(new I18NAwareMessageConsumer(new PrintStream(completions), System.err), progListeners), "\n"); + MessageConsumerOutputStream err = new MessageConsumerOutputStream(new I18NAwareMessageConsumer(System.err, Compiler.this), "\n"); + + codeCompleteFile = file; + codeCompleteLine = line; + codeCompleteCol = col; + callArduinoBuilder(board, vidpid, BuilderAction.CODE_COMPLETE, out, err); + + out.flush(); + err.flush(); + + return completions.toString(); + } + private String VIDPID() { BoardPort boardPort = BaseNoGui.getDiscoveryManager().find(PreferencesData.get("serial.port")); if (boardPort == null) { @@ -208,12 +235,12 @@ private String VIDPID() { return vid.toUpperCase() + "_" + pid.toUpperCase(); } - private PreferencesMap loadPreferences(TargetBoard board, TargetPlatform platform, TargetPackage aPackage, String vidpid) throws RunnerException, IOException { + private PreferencesMap loadPreferences(TargetBoard board, String vidpid) throws RunnerException, IOException { ByteArrayOutputStream stdout = new ByteArrayOutputStream(); ByteArrayOutputStream stderr = new ByteArrayOutputStream(); MessageConsumerOutputStream err = new MessageConsumerOutputStream(new I18NAwareMessageConsumer(new PrintStream(stderr), Compiler.this), "\n"); try { - callArduinoBuilder(board, platform, aPackage, vidpid, BuilderAction.DUMP_PREFS, stdout, err); + callArduinoBuilder(board, vidpid, BuilderAction.DUMP_PREFS, stdout, err); } catch (RunnerException e) { System.err.println(new String(stderr.toByteArray())); throw e; @@ -230,27 +257,22 @@ private void addPathFlagIfPathExists(List cmd, String flag, File folder) } } - private void callArduinoBuilder(TargetBoard board, TargetPlatform platform, TargetPackage aPackage, String vidpid, BuilderAction action, OutputStream outStream, OutputStream errStream) throws RunnerException { + private void callArduinoBuilder(TargetBoard board, String vidpid, BuilderAction action, OutputStream outStream, OutputStream errStream) throws RunnerException { List cmd = new ArrayList<>(); cmd.add(BaseNoGui.getContentFile("arduino-builder").getAbsolutePath()); cmd.add(action.value); + if (action == BuilderAction.CODE_COMPLETE) { + cmd.add(codeCompleteFile.getAbsolutePath() + ":" + codeCompleteLine + ":" + codeCompleteCol); + } cmd.add("-logger=machine"); - File installedPackagesFolder = new File(BaseNoGui.getSettingsFolder(), "packages"); - - addPathFlagIfPathExists(cmd, "-hardware", BaseNoGui.getHardwareFolder()); - addPathFlagIfPathExists(cmd, "-hardware", installedPackagesFolder); - addPathFlagIfPathExists(cmd, "-hardware", BaseNoGui.getSketchbookHardwareFolder()); - - addPathFlagIfPathExists(cmd, "-tools", BaseNoGui.getContentFile("tools-builder")); - addPathFlagIfPathExists(cmd, "-tools", Paths.get(BaseNoGui.getHardwarePath(), "tools", "avr").toFile()); - addPathFlagIfPathExists(cmd, "-tools", installedPackagesFolder); + BaseNoGui.getAllHardwareFolders().forEach(x -> addPathFlagIfPathExists(cmd, "-hardware", x)); + BaseNoGui.getAllToolsFolders().forEach(x -> addPathFlagIfPathExists(cmd, "-tools", x)); addPathFlagIfPathExists(cmd, "-built-in-libraries", BaseNoGui.getContentFile("libraries")); addPathFlagIfPathExists(cmd, "-libraries", BaseNoGui.getSketchbookLibrariesFolder().folder); - String fqbn = Stream.of(aPackage.getId(), platform.getId(), board.getId(), boardOptions(board)).filter(s -> !s.isEmpty()).collect(Collectors.joining(":")); - cmd.add("-fqbn=" + fqbn); + cmd.add("-fqbn=" + getBoardFQBN(board)); if (!"".equals(vidpid)) { cmd.add("-vid-pid=" + vidpid); @@ -280,12 +302,12 @@ private void callArduinoBuilder(TargetBoard board, TargetPlatform platform, Targ } } - //commandLine.addArgument("-debug-level=10", false); - - if (verbose) { + if (verbose && action != BuilderAction.CODE_COMPLETE) { cmd.add("-verbose"); } + cmd.add("-experimental"); + cmd.add(pathToSketch.getAbsolutePath()); if (verbose) { @@ -481,7 +503,17 @@ protected Thread createPump(InputStream is, OutputStream os, boolean closeWhenEx } } - private String boardOptions(TargetBoard board) { + public static String getBoardFQBN(TargetBoard board) { + TargetPlatform plat = board.getContainerPlatform(); + TargetPackage pack = plat.getContainerPackage(); + String fqbn = pack.getId() + ":" + plat.getId() + ":" + board.getId(); + String opts = boardOptions(board); + if (!opts.isEmpty()) + fqbn += ":" + opts; + return fqbn; + } + + private static String boardOptions(TargetBoard board) { return board.getMenuIds().stream() .filter(board::hasMenu) .filter(menuId -> { diff --git a/arduino-core/src/cc/arduino/builder/ArduinoBuilder.java b/arduino-core/src/cc/arduino/builder/ArduinoBuilder.java new file mode 100644 index 00000000000..3c66528be1c --- /dev/null +++ b/arduino-core/src/cc/arduino/builder/ArduinoBuilder.java @@ -0,0 +1,87 @@ +package cc.arduino.builder; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import cc.arduino.Compiler; +import cc.arduino.builder.BuilderGrpc.BuilderBlockingStub; +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import processing.app.BaseNoGui; +import processing.app.debug.MessageSiphon; +import processing.app.debug.TargetBoard; +import processing.app.helpers.ProcessUtils; + +public class ArduinoBuilder { + + private ManagedChannel channel; + private BuilderBlockingStub blockingStub; + // private BuilderStub asyncStub; + + private Process builder; + private MessageSiphon builderOut, builderErr; +// private Exception exception = null; + + public ArduinoBuilder() throws IOException { + channel = ManagedChannelBuilder.forAddress("127.0.0.1", 12345).usePlaintext(true).build(); + blockingStub = BuilderGrpc.newBlockingStub(channel); + // asyncStub = BuilderGrpc.newStub(channel); + + List cmd = new ArrayList<>(); + cmd.add(BaseNoGui.getContentFile("arduino-builder").getAbsolutePath()); + cmd.add("-daemon"); + cmd.add("-experimental"); + builder = ProcessUtils.exec(cmd.toArray(new String[0])); + builderOut = new MessageSiphon(builder.getInputStream(), (msg) -> { + System.out.println(msg); + // try { + // xxx.write(msg.getBytes()); + // } catch (Exception e) { + // exception = new RunnerException(e); + // } + }); + builderErr = new MessageSiphon(builder.getErrorStream(), (msg) -> { + System.err.println(msg); + // try { + // xxx.write(msg.getBytes()); + // } catch (Exception e) { + // exception = new RunnerException(e); + // } + }); + } + + public int close() throws InterruptedException { + builder.destroy(); + builderOut.join(); + builderErr.join(); + return builder.waitFor(); + } + + public String codeComplete(TargetBoard board, File pathToSketch, File requestedFile, int line, int col) { + BuildParams.Builder request = BuildParams.newBuilder(); + + File builtInLibs = BaseNoGui.getContentFile("libraries"); + if (builtInLibs.isDirectory()) { + request.setBuiltInLibrariesFolders(builtInLibs.getAbsolutePath()); + } + request.setCodeCompleteAt(requestedFile.getAbsolutePath() + ":" + line + ":" + col); + request.setFQBN(Compiler.getBoardFQBN(board)); + request.setCustomBuildProperties("build.warn_data_percentage=75"); + String hardwareFolders = BaseNoGui.getAllHardwareFolders().stream().map(x -> x.getAbsolutePath()).collect(Collectors.joining(",")); + request.setHardwareFolders(hardwareFolders); + request.setOtherLibrariesFolders(BaseNoGui.getSketchbookLibrariesFolder().folder.getAbsolutePath()); + request.setArduinoAPIVersion("10805"); + request.setSketchLocation(pathToSketch.getAbsolutePath()); + String toolsFolders = BaseNoGui.getAllToolsFolders().stream().map(x->x.getAbsolutePath()).collect(Collectors.joining(",")); + request.setToolsFolders(toolsFolders); + //request.setVerbose(true); + //request.setWarningsLevel("all"); + //request.setBuildCachePath("/tmp/arduino_cache_761418/"); + Response resp = blockingStub.autocomplete(request.build()); + return resp.getLine(); + } + +} diff --git a/arduino-core/src/cc/arduino/builder/BuildParams.java b/arduino-core/src/cc/arduino/builder/BuildParams.java new file mode 100644 index 00000000000..26eea99eef5 --- /dev/null +++ b/arduino-core/src/cc/arduino/builder/BuildParams.java @@ -0,0 +1,1950 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: builder.proto + +package cc.arduino.builder; + +/** + * Protobuf type {@code proto.BuildParams} + */ +public final class BuildParams extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:proto.BuildParams) + BuildParamsOrBuilder { + // Use BuildParams.newBuilder() to construct. + private BuildParams(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private BuildParams() { + hardwareFolders_ = ""; + toolsFolders_ = ""; + builtInLibrariesFolders_ = ""; + otherLibrariesFolders_ = ""; + sketchLocation_ = ""; + fQBN_ = ""; + arduinoAPIVersion_ = ""; + customBuildProperties_ = ""; + buildCachePath_ = ""; + buildPath_ = ""; + warningsLevel_ = ""; + codeCompleteAt_ = ""; + verbose_ = false; + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return com.google.protobuf.UnknownFieldSet.getDefaultInstance(); + } + private BuildParams( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + int mutable_bitField0_ = 0; + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!input.skipField(tag)) { + done = true; + } + break; + } + case 10: { + java.lang.String s = input.readStringRequireUtf8(); + + hardwareFolders_ = s; + break; + } + case 18: { + java.lang.String s = input.readStringRequireUtf8(); + + toolsFolders_ = s; + break; + } + case 26: { + java.lang.String s = input.readStringRequireUtf8(); + + builtInLibrariesFolders_ = s; + break; + } + case 34: { + java.lang.String s = input.readStringRequireUtf8(); + + otherLibrariesFolders_ = s; + break; + } + case 42: { + java.lang.String s = input.readStringRequireUtf8(); + + sketchLocation_ = s; + break; + } + case 50: { + java.lang.String s = input.readStringRequireUtf8(); + + fQBN_ = s; + break; + } + case 58: { + java.lang.String s = input.readStringRequireUtf8(); + + arduinoAPIVersion_ = s; + break; + } + case 66: { + java.lang.String s = input.readStringRequireUtf8(); + + customBuildProperties_ = s; + break; + } + case 74: { + java.lang.String s = input.readStringRequireUtf8(); + + buildCachePath_ = s; + break; + } + case 82: { + java.lang.String s = input.readStringRequireUtf8(); + + buildPath_ = s; + break; + } + case 90: { + java.lang.String s = input.readStringRequireUtf8(); + + warningsLevel_ = s; + break; + } + case 98: { + java.lang.String s = input.readStringRequireUtf8(); + + codeCompleteAt_ = s; + break; + } + case 104: { + + verbose_ = input.readBool(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cc.arduino.builder.BuilderProto.internal_static_proto_BuildParams_descriptor; + } + + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cc.arduino.builder.BuilderProto.internal_static_proto_BuildParams_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cc.arduino.builder.BuildParams.class, cc.arduino.builder.BuildParams.Builder.class); + } + + public static final int HARDWAREFOLDERS_FIELD_NUMBER = 1; + private volatile java.lang.Object hardwareFolders_; + /** + * optional string hardwareFolders = 1; + */ + public java.lang.String getHardwareFolders() { + java.lang.Object ref = hardwareFolders_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + hardwareFolders_ = s; + return s; + } + } + /** + * optional string hardwareFolders = 1; + */ + public com.google.protobuf.ByteString + getHardwareFoldersBytes() { + java.lang.Object ref = hardwareFolders_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + hardwareFolders_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int TOOLSFOLDERS_FIELD_NUMBER = 2; + private volatile java.lang.Object toolsFolders_; + /** + * optional string toolsFolders = 2; + */ + public java.lang.String getToolsFolders() { + java.lang.Object ref = toolsFolders_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + toolsFolders_ = s; + return s; + } + } + /** + * optional string toolsFolders = 2; + */ + public com.google.protobuf.ByteString + getToolsFoldersBytes() { + java.lang.Object ref = toolsFolders_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + toolsFolders_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int BUILTINLIBRARIESFOLDERS_FIELD_NUMBER = 3; + private volatile java.lang.Object builtInLibrariesFolders_; + /** + * optional string builtInLibrariesFolders = 3; + */ + public java.lang.String getBuiltInLibrariesFolders() { + java.lang.Object ref = builtInLibrariesFolders_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + builtInLibrariesFolders_ = s; + return s; + } + } + /** + * optional string builtInLibrariesFolders = 3; + */ + public com.google.protobuf.ByteString + getBuiltInLibrariesFoldersBytes() { + java.lang.Object ref = builtInLibrariesFolders_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + builtInLibrariesFolders_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int OTHERLIBRARIESFOLDERS_FIELD_NUMBER = 4; + private volatile java.lang.Object otherLibrariesFolders_; + /** + * optional string otherLibrariesFolders = 4; + */ + public java.lang.String getOtherLibrariesFolders() { + java.lang.Object ref = otherLibrariesFolders_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + otherLibrariesFolders_ = s; + return s; + } + } + /** + * optional string otherLibrariesFolders = 4; + */ + public com.google.protobuf.ByteString + getOtherLibrariesFoldersBytes() { + java.lang.Object ref = otherLibrariesFolders_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + otherLibrariesFolders_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int SKETCHLOCATION_FIELD_NUMBER = 5; + private volatile java.lang.Object sketchLocation_; + /** + * optional string sketchLocation = 5; + */ + public java.lang.String getSketchLocation() { + java.lang.Object ref = sketchLocation_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + sketchLocation_ = s; + return s; + } + } + /** + * optional string sketchLocation = 5; + */ + public com.google.protobuf.ByteString + getSketchLocationBytes() { + java.lang.Object ref = sketchLocation_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + sketchLocation_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int FQBN_FIELD_NUMBER = 6; + private volatile java.lang.Object fQBN_; + /** + * optional string fQBN = 6; + */ + public java.lang.String getFQBN() { + java.lang.Object ref = fQBN_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + fQBN_ = s; + return s; + } + } + /** + * optional string fQBN = 6; + */ + public com.google.protobuf.ByteString + getFQBNBytes() { + java.lang.Object ref = fQBN_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fQBN_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int ARDUINOAPIVERSION_FIELD_NUMBER = 7; + private volatile java.lang.Object arduinoAPIVersion_; + /** + * optional string arduinoAPIVersion = 7; + */ + public java.lang.String getArduinoAPIVersion() { + java.lang.Object ref = arduinoAPIVersion_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + arduinoAPIVersion_ = s; + return s; + } + } + /** + * optional string arduinoAPIVersion = 7; + */ + public com.google.protobuf.ByteString + getArduinoAPIVersionBytes() { + java.lang.Object ref = arduinoAPIVersion_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + arduinoAPIVersion_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int CUSTOMBUILDPROPERTIES_FIELD_NUMBER = 8; + private volatile java.lang.Object customBuildProperties_; + /** + * optional string customBuildProperties = 8; + */ + public java.lang.String getCustomBuildProperties() { + java.lang.Object ref = customBuildProperties_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + customBuildProperties_ = s; + return s; + } + } + /** + * optional string customBuildProperties = 8; + */ + public com.google.protobuf.ByteString + getCustomBuildPropertiesBytes() { + java.lang.Object ref = customBuildProperties_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + customBuildProperties_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int BUILDCACHEPATH_FIELD_NUMBER = 9; + private volatile java.lang.Object buildCachePath_; + /** + * optional string buildCachePath = 9; + */ + public java.lang.String getBuildCachePath() { + java.lang.Object ref = buildCachePath_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + buildCachePath_ = s; + return s; + } + } + /** + * optional string buildCachePath = 9; + */ + public com.google.protobuf.ByteString + getBuildCachePathBytes() { + java.lang.Object ref = buildCachePath_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + buildCachePath_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int BUILDPATH_FIELD_NUMBER = 10; + private volatile java.lang.Object buildPath_; + /** + * optional string buildPath = 10; + */ + public java.lang.String getBuildPath() { + java.lang.Object ref = buildPath_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + buildPath_ = s; + return s; + } + } + /** + * optional string buildPath = 10; + */ + public com.google.protobuf.ByteString + getBuildPathBytes() { + java.lang.Object ref = buildPath_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + buildPath_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int WARNINGSLEVEL_FIELD_NUMBER = 11; + private volatile java.lang.Object warningsLevel_; + /** + * optional string warningsLevel = 11; + */ + public java.lang.String getWarningsLevel() { + java.lang.Object ref = warningsLevel_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + warningsLevel_ = s; + return s; + } + } + /** + * optional string warningsLevel = 11; + */ + public com.google.protobuf.ByteString + getWarningsLevelBytes() { + java.lang.Object ref = warningsLevel_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + warningsLevel_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int CODECOMPLETEAT_FIELD_NUMBER = 12; + private volatile java.lang.Object codeCompleteAt_; + /** + * optional string codeCompleteAt = 12; + */ + public java.lang.String getCodeCompleteAt() { + java.lang.Object ref = codeCompleteAt_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + codeCompleteAt_ = s; + return s; + } + } + /** + * optional string codeCompleteAt = 12; + */ + public com.google.protobuf.ByteString + getCodeCompleteAtBytes() { + java.lang.Object ref = codeCompleteAt_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + codeCompleteAt_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int VERBOSE_FIELD_NUMBER = 13; + private boolean verbose_; + /** + * optional bool verbose = 13; + */ + public boolean getVerbose() { + return verbose_; + } + + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (!getHardwareFoldersBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, hardwareFolders_); + } + if (!getToolsFoldersBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 2, toolsFolders_); + } + if (!getBuiltInLibrariesFoldersBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 3, builtInLibrariesFolders_); + } + if (!getOtherLibrariesFoldersBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 4, otherLibrariesFolders_); + } + if (!getSketchLocationBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 5, sketchLocation_); + } + if (!getFQBNBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 6, fQBN_); + } + if (!getArduinoAPIVersionBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 7, arduinoAPIVersion_); + } + if (!getCustomBuildPropertiesBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 8, customBuildProperties_); + } + if (!getBuildCachePathBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 9, buildCachePath_); + } + if (!getBuildPathBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 10, buildPath_); + } + if (!getWarningsLevelBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 11, warningsLevel_); + } + if (!getCodeCompleteAtBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 12, codeCompleteAt_); + } + if (verbose_ != false) { + output.writeBool(13, verbose_); + } + } + + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!getHardwareFoldersBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, hardwareFolders_); + } + if (!getToolsFoldersBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, toolsFolders_); + } + if (!getBuiltInLibrariesFoldersBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, builtInLibrariesFolders_); + } + if (!getOtherLibrariesFoldersBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, otherLibrariesFolders_); + } + if (!getSketchLocationBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, sketchLocation_); + } + if (!getFQBNBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(6, fQBN_); + } + if (!getArduinoAPIVersionBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(7, arduinoAPIVersion_); + } + if (!getCustomBuildPropertiesBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(8, customBuildProperties_); + } + if (!getBuildCachePathBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(9, buildCachePath_); + } + if (!getBuildPathBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(10, buildPath_); + } + if (!getWarningsLevelBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(11, warningsLevel_); + } + if (!getCodeCompleteAtBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(12, codeCompleteAt_); + } + if (verbose_ != false) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(13, verbose_); + } + memoizedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cc.arduino.builder.BuildParams)) { + return super.equals(obj); + } + cc.arduino.builder.BuildParams other = (cc.arduino.builder.BuildParams) obj; + + boolean result = true; + result = result && getHardwareFolders() + .equals(other.getHardwareFolders()); + result = result && getToolsFolders() + .equals(other.getToolsFolders()); + result = result && getBuiltInLibrariesFolders() + .equals(other.getBuiltInLibrariesFolders()); + result = result && getOtherLibrariesFolders() + .equals(other.getOtherLibrariesFolders()); + result = result && getSketchLocation() + .equals(other.getSketchLocation()); + result = result && getFQBN() + .equals(other.getFQBN()); + result = result && getArduinoAPIVersion() + .equals(other.getArduinoAPIVersion()); + result = result && getCustomBuildProperties() + .equals(other.getCustomBuildProperties()); + result = result && getBuildCachePath() + .equals(other.getBuildCachePath()); + result = result && getBuildPath() + .equals(other.getBuildPath()); + result = result && getWarningsLevel() + .equals(other.getWarningsLevel()); + result = result && getCodeCompleteAt() + .equals(other.getCodeCompleteAt()); + result = result && (getVerbose() + == other.getVerbose()); + return result; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptorForType().hashCode(); + hash = (37 * hash) + HARDWAREFOLDERS_FIELD_NUMBER; + hash = (53 * hash) + getHardwareFolders().hashCode(); + hash = (37 * hash) + TOOLSFOLDERS_FIELD_NUMBER; + hash = (53 * hash) + getToolsFolders().hashCode(); + hash = (37 * hash) + BUILTINLIBRARIESFOLDERS_FIELD_NUMBER; + hash = (53 * hash) + getBuiltInLibrariesFolders().hashCode(); + hash = (37 * hash) + OTHERLIBRARIESFOLDERS_FIELD_NUMBER; + hash = (53 * hash) + getOtherLibrariesFolders().hashCode(); + hash = (37 * hash) + SKETCHLOCATION_FIELD_NUMBER; + hash = (53 * hash) + getSketchLocation().hashCode(); + hash = (37 * hash) + FQBN_FIELD_NUMBER; + hash = (53 * hash) + getFQBN().hashCode(); + hash = (37 * hash) + ARDUINOAPIVERSION_FIELD_NUMBER; + hash = (53 * hash) + getArduinoAPIVersion().hashCode(); + hash = (37 * hash) + CUSTOMBUILDPROPERTIES_FIELD_NUMBER; + hash = (53 * hash) + getCustomBuildProperties().hashCode(); + hash = (37 * hash) + BUILDCACHEPATH_FIELD_NUMBER; + hash = (53 * hash) + getBuildCachePath().hashCode(); + hash = (37 * hash) + BUILDPATH_FIELD_NUMBER; + hash = (53 * hash) + getBuildPath().hashCode(); + hash = (37 * hash) + WARNINGSLEVEL_FIELD_NUMBER; + hash = (53 * hash) + getWarningsLevel().hashCode(); + hash = (37 * hash) + CODECOMPLETEAT_FIELD_NUMBER; + hash = (53 * hash) + getCodeCompleteAt().hashCode(); + hash = (37 * hash) + VERBOSE_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean( + getVerbose()); + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cc.arduino.builder.BuildParams parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cc.arduino.builder.BuildParams parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cc.arduino.builder.BuildParams parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cc.arduino.builder.BuildParams parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cc.arduino.builder.BuildParams parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cc.arduino.builder.BuildParams parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cc.arduino.builder.BuildParams parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cc.arduino.builder.BuildParams parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cc.arduino.builder.BuildParams parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cc.arduino.builder.BuildParams parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cc.arduino.builder.BuildParams prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code proto.BuildParams} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:proto.BuildParams) + cc.arduino.builder.BuildParamsOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cc.arduino.builder.BuilderProto.internal_static_proto_BuildParams_descriptor; + } + + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cc.arduino.builder.BuilderProto.internal_static_proto_BuildParams_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cc.arduino.builder.BuildParams.class, cc.arduino.builder.BuildParams.Builder.class); + } + + // Construct using cc.arduino.builder.BuildParams.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + public Builder clear() { + super.clear(); + hardwareFolders_ = ""; + + toolsFolders_ = ""; + + builtInLibrariesFolders_ = ""; + + otherLibrariesFolders_ = ""; + + sketchLocation_ = ""; + + fQBN_ = ""; + + arduinoAPIVersion_ = ""; + + customBuildProperties_ = ""; + + buildCachePath_ = ""; + + buildPath_ = ""; + + warningsLevel_ = ""; + + codeCompleteAt_ = ""; + + verbose_ = false; + + return this; + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cc.arduino.builder.BuilderProto.internal_static_proto_BuildParams_descriptor; + } + + public cc.arduino.builder.BuildParams getDefaultInstanceForType() { + return cc.arduino.builder.BuildParams.getDefaultInstance(); + } + + public cc.arduino.builder.BuildParams build() { + cc.arduino.builder.BuildParams result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public cc.arduino.builder.BuildParams buildPartial() { + cc.arduino.builder.BuildParams result = new cc.arduino.builder.BuildParams(this); + result.hardwareFolders_ = hardwareFolders_; + result.toolsFolders_ = toolsFolders_; + result.builtInLibrariesFolders_ = builtInLibrariesFolders_; + result.otherLibrariesFolders_ = otherLibrariesFolders_; + result.sketchLocation_ = sketchLocation_; + result.fQBN_ = fQBN_; + result.arduinoAPIVersion_ = arduinoAPIVersion_; + result.customBuildProperties_ = customBuildProperties_; + result.buildCachePath_ = buildCachePath_; + result.buildPath_ = buildPath_; + result.warningsLevel_ = warningsLevel_; + result.codeCompleteAt_ = codeCompleteAt_; + result.verbose_ = verbose_; + onBuilt(); + return result; + } + + public Builder clone() { + return (Builder) super.clone(); + } + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return (Builder) super.setField(field, value); + } + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return (Builder) super.clearField(field); + } + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return (Builder) super.clearOneof(oneof); + } + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, Object value) { + return (Builder) super.setRepeatedField(field, index, value); + } + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return (Builder) super.addRepeatedField(field, value); + } + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cc.arduino.builder.BuildParams) { + return mergeFrom((cc.arduino.builder.BuildParams)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cc.arduino.builder.BuildParams other) { + if (other == cc.arduino.builder.BuildParams.getDefaultInstance()) return this; + if (!other.getHardwareFolders().isEmpty()) { + hardwareFolders_ = other.hardwareFolders_; + onChanged(); + } + if (!other.getToolsFolders().isEmpty()) { + toolsFolders_ = other.toolsFolders_; + onChanged(); + } + if (!other.getBuiltInLibrariesFolders().isEmpty()) { + builtInLibrariesFolders_ = other.builtInLibrariesFolders_; + onChanged(); + } + if (!other.getOtherLibrariesFolders().isEmpty()) { + otherLibrariesFolders_ = other.otherLibrariesFolders_; + onChanged(); + } + if (!other.getSketchLocation().isEmpty()) { + sketchLocation_ = other.sketchLocation_; + onChanged(); + } + if (!other.getFQBN().isEmpty()) { + fQBN_ = other.fQBN_; + onChanged(); + } + if (!other.getArduinoAPIVersion().isEmpty()) { + arduinoAPIVersion_ = other.arduinoAPIVersion_; + onChanged(); + } + if (!other.getCustomBuildProperties().isEmpty()) { + customBuildProperties_ = other.customBuildProperties_; + onChanged(); + } + if (!other.getBuildCachePath().isEmpty()) { + buildCachePath_ = other.buildCachePath_; + onChanged(); + } + if (!other.getBuildPath().isEmpty()) { + buildPath_ = other.buildPath_; + onChanged(); + } + if (!other.getWarningsLevel().isEmpty()) { + warningsLevel_ = other.warningsLevel_; + onChanged(); + } + if (!other.getCodeCompleteAt().isEmpty()) { + codeCompleteAt_ = other.codeCompleteAt_; + onChanged(); + } + if (other.getVerbose() != false) { + setVerbose(other.getVerbose()); + } + onChanged(); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + cc.arduino.builder.BuildParams parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (cc.arduino.builder.BuildParams) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private java.lang.Object hardwareFolders_ = ""; + /** + * optional string hardwareFolders = 1; + */ + public java.lang.String getHardwareFolders() { + java.lang.Object ref = hardwareFolders_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + hardwareFolders_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string hardwareFolders = 1; + */ + public com.google.protobuf.ByteString + getHardwareFoldersBytes() { + java.lang.Object ref = hardwareFolders_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + hardwareFolders_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string hardwareFolders = 1; + */ + public Builder setHardwareFolders( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + hardwareFolders_ = value; + onChanged(); + return this; + } + /** + * optional string hardwareFolders = 1; + */ + public Builder clearHardwareFolders() { + + hardwareFolders_ = getDefaultInstance().getHardwareFolders(); + onChanged(); + return this; + } + /** + * optional string hardwareFolders = 1; + */ + public Builder setHardwareFoldersBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + hardwareFolders_ = value; + onChanged(); + return this; + } + + private java.lang.Object toolsFolders_ = ""; + /** + * optional string toolsFolders = 2; + */ + public java.lang.String getToolsFolders() { + java.lang.Object ref = toolsFolders_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + toolsFolders_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string toolsFolders = 2; + */ + public com.google.protobuf.ByteString + getToolsFoldersBytes() { + java.lang.Object ref = toolsFolders_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + toolsFolders_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string toolsFolders = 2; + */ + public Builder setToolsFolders( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + toolsFolders_ = value; + onChanged(); + return this; + } + /** + * optional string toolsFolders = 2; + */ + public Builder clearToolsFolders() { + + toolsFolders_ = getDefaultInstance().getToolsFolders(); + onChanged(); + return this; + } + /** + * optional string toolsFolders = 2; + */ + public Builder setToolsFoldersBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + toolsFolders_ = value; + onChanged(); + return this; + } + + private java.lang.Object builtInLibrariesFolders_ = ""; + /** + * optional string builtInLibrariesFolders = 3; + */ + public java.lang.String getBuiltInLibrariesFolders() { + java.lang.Object ref = builtInLibrariesFolders_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + builtInLibrariesFolders_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string builtInLibrariesFolders = 3; + */ + public com.google.protobuf.ByteString + getBuiltInLibrariesFoldersBytes() { + java.lang.Object ref = builtInLibrariesFolders_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + builtInLibrariesFolders_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string builtInLibrariesFolders = 3; + */ + public Builder setBuiltInLibrariesFolders( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + builtInLibrariesFolders_ = value; + onChanged(); + return this; + } + /** + * optional string builtInLibrariesFolders = 3; + */ + public Builder clearBuiltInLibrariesFolders() { + + builtInLibrariesFolders_ = getDefaultInstance().getBuiltInLibrariesFolders(); + onChanged(); + return this; + } + /** + * optional string builtInLibrariesFolders = 3; + */ + public Builder setBuiltInLibrariesFoldersBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + builtInLibrariesFolders_ = value; + onChanged(); + return this; + } + + private java.lang.Object otherLibrariesFolders_ = ""; + /** + * optional string otherLibrariesFolders = 4; + */ + public java.lang.String getOtherLibrariesFolders() { + java.lang.Object ref = otherLibrariesFolders_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + otherLibrariesFolders_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string otherLibrariesFolders = 4; + */ + public com.google.protobuf.ByteString + getOtherLibrariesFoldersBytes() { + java.lang.Object ref = otherLibrariesFolders_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + otherLibrariesFolders_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string otherLibrariesFolders = 4; + */ + public Builder setOtherLibrariesFolders( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + otherLibrariesFolders_ = value; + onChanged(); + return this; + } + /** + * optional string otherLibrariesFolders = 4; + */ + public Builder clearOtherLibrariesFolders() { + + otherLibrariesFolders_ = getDefaultInstance().getOtherLibrariesFolders(); + onChanged(); + return this; + } + /** + * optional string otherLibrariesFolders = 4; + */ + public Builder setOtherLibrariesFoldersBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + otherLibrariesFolders_ = value; + onChanged(); + return this; + } + + private java.lang.Object sketchLocation_ = ""; + /** + * optional string sketchLocation = 5; + */ + public java.lang.String getSketchLocation() { + java.lang.Object ref = sketchLocation_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + sketchLocation_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string sketchLocation = 5; + */ + public com.google.protobuf.ByteString + getSketchLocationBytes() { + java.lang.Object ref = sketchLocation_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + sketchLocation_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string sketchLocation = 5; + */ + public Builder setSketchLocation( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + sketchLocation_ = value; + onChanged(); + return this; + } + /** + * optional string sketchLocation = 5; + */ + public Builder clearSketchLocation() { + + sketchLocation_ = getDefaultInstance().getSketchLocation(); + onChanged(); + return this; + } + /** + * optional string sketchLocation = 5; + */ + public Builder setSketchLocationBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + sketchLocation_ = value; + onChanged(); + return this; + } + + private java.lang.Object fQBN_ = ""; + /** + * optional string fQBN = 6; + */ + public java.lang.String getFQBN() { + java.lang.Object ref = fQBN_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + fQBN_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string fQBN = 6; + */ + public com.google.protobuf.ByteString + getFQBNBytes() { + java.lang.Object ref = fQBN_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + fQBN_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string fQBN = 6; + */ + public Builder setFQBN( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + fQBN_ = value; + onChanged(); + return this; + } + /** + * optional string fQBN = 6; + */ + public Builder clearFQBN() { + + fQBN_ = getDefaultInstance().getFQBN(); + onChanged(); + return this; + } + /** + * optional string fQBN = 6; + */ + public Builder setFQBNBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + fQBN_ = value; + onChanged(); + return this; + } + + private java.lang.Object arduinoAPIVersion_ = ""; + /** + * optional string arduinoAPIVersion = 7; + */ + public java.lang.String getArduinoAPIVersion() { + java.lang.Object ref = arduinoAPIVersion_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + arduinoAPIVersion_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string arduinoAPIVersion = 7; + */ + public com.google.protobuf.ByteString + getArduinoAPIVersionBytes() { + java.lang.Object ref = arduinoAPIVersion_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + arduinoAPIVersion_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string arduinoAPIVersion = 7; + */ + public Builder setArduinoAPIVersion( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + arduinoAPIVersion_ = value; + onChanged(); + return this; + } + /** + * optional string arduinoAPIVersion = 7; + */ + public Builder clearArduinoAPIVersion() { + + arduinoAPIVersion_ = getDefaultInstance().getArduinoAPIVersion(); + onChanged(); + return this; + } + /** + * optional string arduinoAPIVersion = 7; + */ + public Builder setArduinoAPIVersionBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + arduinoAPIVersion_ = value; + onChanged(); + return this; + } + + private java.lang.Object customBuildProperties_ = ""; + /** + * optional string customBuildProperties = 8; + */ + public java.lang.String getCustomBuildProperties() { + java.lang.Object ref = customBuildProperties_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + customBuildProperties_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string customBuildProperties = 8; + */ + public com.google.protobuf.ByteString + getCustomBuildPropertiesBytes() { + java.lang.Object ref = customBuildProperties_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + customBuildProperties_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string customBuildProperties = 8; + */ + public Builder setCustomBuildProperties( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + customBuildProperties_ = value; + onChanged(); + return this; + } + /** + * optional string customBuildProperties = 8; + */ + public Builder clearCustomBuildProperties() { + + customBuildProperties_ = getDefaultInstance().getCustomBuildProperties(); + onChanged(); + return this; + } + /** + * optional string customBuildProperties = 8; + */ + public Builder setCustomBuildPropertiesBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + customBuildProperties_ = value; + onChanged(); + return this; + } + + private java.lang.Object buildCachePath_ = ""; + /** + * optional string buildCachePath = 9; + */ + public java.lang.String getBuildCachePath() { + java.lang.Object ref = buildCachePath_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + buildCachePath_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string buildCachePath = 9; + */ + public com.google.protobuf.ByteString + getBuildCachePathBytes() { + java.lang.Object ref = buildCachePath_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + buildCachePath_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string buildCachePath = 9; + */ + public Builder setBuildCachePath( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + buildCachePath_ = value; + onChanged(); + return this; + } + /** + * optional string buildCachePath = 9; + */ + public Builder clearBuildCachePath() { + + buildCachePath_ = getDefaultInstance().getBuildCachePath(); + onChanged(); + return this; + } + /** + * optional string buildCachePath = 9; + */ + public Builder setBuildCachePathBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + buildCachePath_ = value; + onChanged(); + return this; + } + + private java.lang.Object buildPath_ = ""; + /** + * optional string buildPath = 10; + */ + public java.lang.String getBuildPath() { + java.lang.Object ref = buildPath_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + buildPath_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string buildPath = 10; + */ + public com.google.protobuf.ByteString + getBuildPathBytes() { + java.lang.Object ref = buildPath_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + buildPath_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string buildPath = 10; + */ + public Builder setBuildPath( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + buildPath_ = value; + onChanged(); + return this; + } + /** + * optional string buildPath = 10; + */ + public Builder clearBuildPath() { + + buildPath_ = getDefaultInstance().getBuildPath(); + onChanged(); + return this; + } + /** + * optional string buildPath = 10; + */ + public Builder setBuildPathBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + buildPath_ = value; + onChanged(); + return this; + } + + private java.lang.Object warningsLevel_ = ""; + /** + * optional string warningsLevel = 11; + */ + public java.lang.String getWarningsLevel() { + java.lang.Object ref = warningsLevel_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + warningsLevel_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string warningsLevel = 11; + */ + public com.google.protobuf.ByteString + getWarningsLevelBytes() { + java.lang.Object ref = warningsLevel_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + warningsLevel_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string warningsLevel = 11; + */ + public Builder setWarningsLevel( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + warningsLevel_ = value; + onChanged(); + return this; + } + /** + * optional string warningsLevel = 11; + */ + public Builder clearWarningsLevel() { + + warningsLevel_ = getDefaultInstance().getWarningsLevel(); + onChanged(); + return this; + } + /** + * optional string warningsLevel = 11; + */ + public Builder setWarningsLevelBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + warningsLevel_ = value; + onChanged(); + return this; + } + + private java.lang.Object codeCompleteAt_ = ""; + /** + * optional string codeCompleteAt = 12; + */ + public java.lang.String getCodeCompleteAt() { + java.lang.Object ref = codeCompleteAt_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + codeCompleteAt_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string codeCompleteAt = 12; + */ + public com.google.protobuf.ByteString + getCodeCompleteAtBytes() { + java.lang.Object ref = codeCompleteAt_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + codeCompleteAt_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string codeCompleteAt = 12; + */ + public Builder setCodeCompleteAt( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + codeCompleteAt_ = value; + onChanged(); + return this; + } + /** + * optional string codeCompleteAt = 12; + */ + public Builder clearCodeCompleteAt() { + + codeCompleteAt_ = getDefaultInstance().getCodeCompleteAt(); + onChanged(); + return this; + } + /** + * optional string codeCompleteAt = 12; + */ + public Builder setCodeCompleteAtBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + codeCompleteAt_ = value; + onChanged(); + return this; + } + + private boolean verbose_ ; + /** + * optional bool verbose = 13; + */ + public boolean getVerbose() { + return verbose_; + } + /** + * optional bool verbose = 13; + */ + public Builder setVerbose(boolean value) { + + verbose_ = value; + onChanged(); + return this; + } + /** + * optional bool verbose = 13; + */ + public Builder clearVerbose() { + + verbose_ = false; + onChanged(); + return this; + } + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return this; + } + + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return this; + } + + + // @@protoc_insertion_point(builder_scope:proto.BuildParams) + } + + // @@protoc_insertion_point(class_scope:proto.BuildParams) + private static final cc.arduino.builder.BuildParams DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cc.arduino.builder.BuildParams(); + } + + public static cc.arduino.builder.BuildParams getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + public BuildParams parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new BuildParams(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + public cc.arduino.builder.BuildParams getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + +} + diff --git a/arduino-core/src/cc/arduino/builder/BuildParamsOrBuilder.java b/arduino-core/src/cc/arduino/builder/BuildParamsOrBuilder.java new file mode 100644 index 00000000000..ef55236fadd --- /dev/null +++ b/arduino-core/src/cc/arduino/builder/BuildParamsOrBuilder.java @@ -0,0 +1,134 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: builder.proto + +package cc.arduino.builder; + +public interface BuildParamsOrBuilder extends + // @@protoc_insertion_point(interface_extends:proto.BuildParams) + com.google.protobuf.MessageOrBuilder { + + /** + * optional string hardwareFolders = 1; + */ + java.lang.String getHardwareFolders(); + /** + * optional string hardwareFolders = 1; + */ + com.google.protobuf.ByteString + getHardwareFoldersBytes(); + + /** + * optional string toolsFolders = 2; + */ + java.lang.String getToolsFolders(); + /** + * optional string toolsFolders = 2; + */ + com.google.protobuf.ByteString + getToolsFoldersBytes(); + + /** + * optional string builtInLibrariesFolders = 3; + */ + java.lang.String getBuiltInLibrariesFolders(); + /** + * optional string builtInLibrariesFolders = 3; + */ + com.google.protobuf.ByteString + getBuiltInLibrariesFoldersBytes(); + + /** + * optional string otherLibrariesFolders = 4; + */ + java.lang.String getOtherLibrariesFolders(); + /** + * optional string otherLibrariesFolders = 4; + */ + com.google.protobuf.ByteString + getOtherLibrariesFoldersBytes(); + + /** + * optional string sketchLocation = 5; + */ + java.lang.String getSketchLocation(); + /** + * optional string sketchLocation = 5; + */ + com.google.protobuf.ByteString + getSketchLocationBytes(); + + /** + * optional string fQBN = 6; + */ + java.lang.String getFQBN(); + /** + * optional string fQBN = 6; + */ + com.google.protobuf.ByteString + getFQBNBytes(); + + /** + * optional string arduinoAPIVersion = 7; + */ + java.lang.String getArduinoAPIVersion(); + /** + * optional string arduinoAPIVersion = 7; + */ + com.google.protobuf.ByteString + getArduinoAPIVersionBytes(); + + /** + * optional string customBuildProperties = 8; + */ + java.lang.String getCustomBuildProperties(); + /** + * optional string customBuildProperties = 8; + */ + com.google.protobuf.ByteString + getCustomBuildPropertiesBytes(); + + /** + * optional string buildCachePath = 9; + */ + java.lang.String getBuildCachePath(); + /** + * optional string buildCachePath = 9; + */ + com.google.protobuf.ByteString + getBuildCachePathBytes(); + + /** + * optional string buildPath = 10; + */ + java.lang.String getBuildPath(); + /** + * optional string buildPath = 10; + */ + com.google.protobuf.ByteString + getBuildPathBytes(); + + /** + * optional string warningsLevel = 11; + */ + java.lang.String getWarningsLevel(); + /** + * optional string warningsLevel = 11; + */ + com.google.protobuf.ByteString + getWarningsLevelBytes(); + + /** + * optional string codeCompleteAt = 12; + */ + java.lang.String getCodeCompleteAt(); + /** + * optional string codeCompleteAt = 12; + */ + com.google.protobuf.ByteString + getCodeCompleteAtBytes(); + + /** + * optional bool verbose = 13; + */ + boolean getVerbose(); +} diff --git a/arduino-core/src/cc/arduino/builder/BuilderGrpc.java b/arduino-core/src/cc/arduino/builder/BuilderGrpc.java new file mode 100644 index 00000000000..3eb2c52f40e --- /dev/null +++ b/arduino-core/src/cc/arduino/builder/BuilderGrpc.java @@ -0,0 +1,311 @@ +package cc.arduino.builder; + +import static io.grpc.MethodDescriptor.generateFullMethodName; +import static io.grpc.stub.ClientCalls.asyncServerStreamingCall; +import static io.grpc.stub.ClientCalls.asyncUnaryCall; +import static io.grpc.stub.ClientCalls.blockingServerStreamingCall; +import static io.grpc.stub.ClientCalls.blockingUnaryCall; +import static io.grpc.stub.ClientCalls.futureUnaryCall; +import static io.grpc.stub.ServerCalls.asyncServerStreamingCall; +import static io.grpc.stub.ServerCalls.asyncUnaryCall; +import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall; + +/** + *
+ * Interface exported by the server.
+ * 
+ */ +@javax.annotation.Generated( + value = "by gRPC proto compiler (version 1.6.1)", + comments = "Source: builder.proto") +public final class BuilderGrpc { + + private BuilderGrpc() {} + + public static final String SERVICE_NAME = "proto.Builder"; + + // Static method descriptors that strictly reflect the proto. + @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901") + public static final io.grpc.MethodDescriptor METHOD_BUILD = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING) + .setFullMethodName(generateFullMethodName( + "proto.Builder", "Build")) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cc.arduino.builder.BuildParams.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cc.arduino.builder.Response.getDefaultInstance())) + .build(); + @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/1901") + public static final io.grpc.MethodDescriptor METHOD_AUTOCOMPLETE = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName( + "proto.Builder", "Autocomplete")) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cc.arduino.builder.BuildParams.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cc.arduino.builder.Response.getDefaultInstance())) + .build(); + + /** + * Creates a new async stub that supports all call types for the service + */ + public static BuilderStub newStub(io.grpc.Channel channel) { + return new BuilderStub(channel); + } + + /** + * Creates a new blocking-style stub that supports unary and streaming output calls on the service + */ + public static BuilderBlockingStub newBlockingStub( + io.grpc.Channel channel) { + return new BuilderBlockingStub(channel); + } + + /** + * Creates a new ListenableFuture-style stub that supports unary calls on the service + */ + public static BuilderFutureStub newFutureStub( + io.grpc.Channel channel) { + return new BuilderFutureStub(channel); + } + + /** + *
+   * Interface exported by the server.
+   * 
+ */ + public static abstract class BuilderImplBase implements io.grpc.BindableService { + + /** + *
+     * A server-to-client streaming RPC.
+     * Obtains the Features available within the given Rectangle.  Results are
+     * streamed rather than returned at once (e.g. in a response message with a
+     * repeated field), as the rectangle may cover a large area and contain a
+     * huge number of features.
+     * 
+ */ + public void build(cc.arduino.builder.BuildParams request, + io.grpc.stub.StreamObserver responseObserver) { + asyncUnimplementedUnaryCall(METHOD_BUILD, responseObserver); + } + + /** + */ + public void autocomplete(cc.arduino.builder.BuildParams request, + io.grpc.stub.StreamObserver responseObserver) { + asyncUnimplementedUnaryCall(METHOD_AUTOCOMPLETE, responseObserver); + } + + @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() { + return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) + .addMethod( + METHOD_BUILD, + asyncServerStreamingCall( + new MethodHandlers< + cc.arduino.builder.BuildParams, + cc.arduino.builder.Response>( + this, METHODID_BUILD))) + .addMethod( + METHOD_AUTOCOMPLETE, + asyncUnaryCall( + new MethodHandlers< + cc.arduino.builder.BuildParams, + cc.arduino.builder.Response>( + this, METHODID_AUTOCOMPLETE))) + .build(); + } + } + + /** + *
+   * Interface exported by the server.
+   * 
+ */ + public static final class BuilderStub extends io.grpc.stub.AbstractStub { + private BuilderStub(io.grpc.Channel channel) { + super(channel); + } + + private BuilderStub(io.grpc.Channel channel, + io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected BuilderStub build(io.grpc.Channel channel, + io.grpc.CallOptions callOptions) { + return new BuilderStub(channel, callOptions); + } + + /** + *
+     * A server-to-client streaming RPC.
+     * Obtains the Features available within the given Rectangle.  Results are
+     * streamed rather than returned at once (e.g. in a response message with a
+     * repeated field), as the rectangle may cover a large area and contain a
+     * huge number of features.
+     * 
+ */ + public void build(cc.arduino.builder.BuildParams request, + io.grpc.stub.StreamObserver responseObserver) { + asyncServerStreamingCall( + getChannel().newCall(METHOD_BUILD, getCallOptions()), request, responseObserver); + } + + /** + */ + public void autocomplete(cc.arduino.builder.BuildParams request, + io.grpc.stub.StreamObserver responseObserver) { + asyncUnaryCall( + getChannel().newCall(METHOD_AUTOCOMPLETE, getCallOptions()), request, responseObserver); + } + } + + /** + *
+   * Interface exported by the server.
+   * 
+ */ + public static final class BuilderBlockingStub extends io.grpc.stub.AbstractStub { + private BuilderBlockingStub(io.grpc.Channel channel) { + super(channel); + } + + private BuilderBlockingStub(io.grpc.Channel channel, + io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected BuilderBlockingStub build(io.grpc.Channel channel, + io.grpc.CallOptions callOptions) { + return new BuilderBlockingStub(channel, callOptions); + } + + /** + *
+     * A server-to-client streaming RPC.
+     * Obtains the Features available within the given Rectangle.  Results are
+     * streamed rather than returned at once (e.g. in a response message with a
+     * repeated field), as the rectangle may cover a large area and contain a
+     * huge number of features.
+     * 
+ */ + public java.util.Iterator build( + cc.arduino.builder.BuildParams request) { + return blockingServerStreamingCall( + getChannel(), METHOD_BUILD, getCallOptions(), request); + } + + /** + */ + public cc.arduino.builder.Response autocomplete(cc.arduino.builder.BuildParams request) { + return blockingUnaryCall( + getChannel(), METHOD_AUTOCOMPLETE, getCallOptions(), request); + } + } + + /** + *
+   * Interface exported by the server.
+   * 
+ */ + public static final class BuilderFutureStub extends io.grpc.stub.AbstractStub { + private BuilderFutureStub(io.grpc.Channel channel) { + super(channel); + } + + private BuilderFutureStub(io.grpc.Channel channel, + io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected BuilderFutureStub build(io.grpc.Channel channel, + io.grpc.CallOptions callOptions) { + return new BuilderFutureStub(channel, callOptions); + } + + /** + */ + public com.google.common.util.concurrent.ListenableFuture autocomplete( + cc.arduino.builder.BuildParams request) { + return futureUnaryCall( + getChannel().newCall(METHOD_AUTOCOMPLETE, getCallOptions()), request); + } + } + + private static final int METHODID_BUILD = 0; + private static final int METHODID_AUTOCOMPLETE = 1; + + private static final class MethodHandlers implements + io.grpc.stub.ServerCalls.UnaryMethod, + io.grpc.stub.ServerCalls.ServerStreamingMethod, + io.grpc.stub.ServerCalls.ClientStreamingMethod, + io.grpc.stub.ServerCalls.BidiStreamingMethod { + private final BuilderImplBase serviceImpl; + private final int methodId; + + MethodHandlers(BuilderImplBase serviceImpl, int methodId) { + this.serviceImpl = serviceImpl; + this.methodId = methodId; + } + + @java.lang.Override + @java.lang.SuppressWarnings("unchecked") + public void invoke(Req request, io.grpc.stub.StreamObserver responseObserver) { + switch (methodId) { + case METHODID_BUILD: + serviceImpl.build((cc.arduino.builder.BuildParams) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + case METHODID_AUTOCOMPLETE: + serviceImpl.autocomplete((cc.arduino.builder.BuildParams) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + default: + throw new AssertionError(); + } + } + + @java.lang.Override + public io.grpc.stub.StreamObserver invoke( + io.grpc.stub.StreamObserver responseObserver) { + switch (methodId) { + default: + throw new AssertionError(); + } + } + } + + private static final class BuilderDescriptorSupplier implements io.grpc.protobuf.ProtoFileDescriptorSupplier { + @java.lang.Override + public com.google.protobuf.Descriptors.FileDescriptor getFileDescriptor() { + return cc.arduino.builder.BuilderProto.getDescriptor(); + } + } + + private static volatile io.grpc.ServiceDescriptor serviceDescriptor; + + public static io.grpc.ServiceDescriptor getServiceDescriptor() { + io.grpc.ServiceDescriptor result = serviceDescriptor; + if (result == null) { + synchronized (BuilderGrpc.class) { + result = serviceDescriptor; + if (result == null) { + serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME) + .setSchemaDescriptor(new BuilderDescriptorSupplier()) + .addMethod(METHOD_BUILD) + .addMethod(METHOD_AUTOCOMPLETE) + .build(); + } + } + } + return result; + } +} diff --git a/arduino-core/src/cc/arduino/builder/BuilderProto.java b/arduino-core/src/cc/arduino/builder/BuilderProto.java new file mode 100644 index 00000000000..ec4214ef5ca --- /dev/null +++ b/arduino-core/src/cc/arduino/builder/BuilderProto.java @@ -0,0 +1,78 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: builder.proto + +package cc.arduino.builder; + +public final class BuilderProto { + private BuilderProto() {} + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistryLite registry) { + } + + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistry registry) { + registerAllExtensions( + (com.google.protobuf.ExtensionRegistryLite) registry); + } + static final com.google.protobuf.Descriptors.Descriptor + internal_static_proto_BuildParams_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_proto_BuildParams_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_proto_Response_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_proto_Response_fieldAccessorTable; + + public static com.google.protobuf.Descriptors.FileDescriptor + getDescriptor() { + return descriptor; + } + private static com.google.protobuf.Descriptors.FileDescriptor + descriptor; + static { + java.lang.String[] descriptorData = { + "\n\rbuilder.proto\022\005proto\"\307\002\n\013BuildParams\022\027" + + "\n\017hardwareFolders\030\001 \001(\t\022\024\n\014toolsFolders\030" + + "\002 \001(\t\022\037\n\027builtInLibrariesFolders\030\003 \001(\t\022\035" + + "\n\025otherLibrariesFolders\030\004 \001(\t\022\026\n\016sketchL" + + "ocation\030\005 \001(\t\022\014\n\004fQBN\030\006 \001(\t\022\031\n\021arduinoAP" + + "IVersion\030\007 \001(\t\022\035\n\025customBuildProperties\030" + + "\010 \001(\t\022\026\n\016buildCachePath\030\t \001(\t\022\021\n\tbuildPa" + + "th\030\n \001(\t\022\025\n\rwarningsLevel\030\013 \001(\t\022\026\n\016codeC" + + "ompleteAt\030\014 \001(\t\022\017\n\007verbose\030\r \001(\010\"\030\n\010Resp" + + "onse\022\014\n\004line\030\001 \001(\t2r\n\007Builder\0220\n\005Build\022\022", + ".proto.BuildParams\032\017.proto.Response\"\0000\001\022" + + "5\n\014Autocomplete\022\022.proto.BuildParams\032\017.pr" + + "oto.Response\"\000B$\n\022cc.arduino.builderB\014Bu" + + "ilderProtoP\001b\006proto3" + }; + com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = + new com.google.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() { + public com.google.protobuf.ExtensionRegistry assignDescriptors( + com.google.protobuf.Descriptors.FileDescriptor root) { + descriptor = root; + return null; + } + }; + com.google.protobuf.Descriptors.FileDescriptor + .internalBuildGeneratedFileFrom(descriptorData, + new com.google.protobuf.Descriptors.FileDescriptor[] { + }, assigner); + internal_static_proto_BuildParams_descriptor = + getDescriptor().getMessageTypes().get(0); + internal_static_proto_BuildParams_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_proto_BuildParams_descriptor, + new java.lang.String[] { "HardwareFolders", "ToolsFolders", "BuiltInLibrariesFolders", "OtherLibrariesFolders", "SketchLocation", "FQBN", "ArduinoAPIVersion", "CustomBuildProperties", "BuildCachePath", "BuildPath", "WarningsLevel", "CodeCompleteAt", "Verbose", }); + internal_static_proto_Response_descriptor = + getDescriptor().getMessageTypes().get(1); + internal_static_proto_Response_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_proto_Response_descriptor, + new java.lang.String[] { "Line", }); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/arduino-core/src/cc/arduino/builder/Response.java b/arduino-core/src/cc/arduino/builder/Response.java new file mode 100644 index 00000000000..a83b76e5042 --- /dev/null +++ b/arduino-core/src/cc/arduino/builder/Response.java @@ -0,0 +1,494 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: builder.proto + +package cc.arduino.builder; + +/** + * Protobuf type {@code proto.Response} + */ +public final class Response extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:proto.Response) + ResponseOrBuilder { + // Use Response.newBuilder() to construct. + private Response(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private Response() { + line_ = ""; + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return com.google.protobuf.UnknownFieldSet.getDefaultInstance(); + } + private Response( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + int mutable_bitField0_ = 0; + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!input.skipField(tag)) { + done = true; + } + break; + } + case 10: { + java.lang.String s = input.readStringRequireUtf8(); + + line_ = s; + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cc.arduino.builder.BuilderProto.internal_static_proto_Response_descriptor; + } + + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cc.arduino.builder.BuilderProto.internal_static_proto_Response_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cc.arduino.builder.Response.class, cc.arduino.builder.Response.Builder.class); + } + + public static final int LINE_FIELD_NUMBER = 1; + private volatile java.lang.Object line_; + /** + * optional string line = 1; + */ + public java.lang.String getLine() { + java.lang.Object ref = line_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + line_ = s; + return s; + } + } + /** + * optional string line = 1; + */ + public com.google.protobuf.ByteString + getLineBytes() { + java.lang.Object ref = line_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + line_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (!getLineBytes().isEmpty()) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, line_); + } + } + + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!getLineBytes().isEmpty()) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, line_); + } + memoizedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cc.arduino.builder.Response)) { + return super.equals(obj); + } + cc.arduino.builder.Response other = (cc.arduino.builder.Response) obj; + + boolean result = true; + result = result && getLine() + .equals(other.getLine()); + return result; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptorForType().hashCode(); + hash = (37 * hash) + LINE_FIELD_NUMBER; + hash = (53 * hash) + getLine().hashCode(); + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cc.arduino.builder.Response parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cc.arduino.builder.Response parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cc.arduino.builder.Response parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cc.arduino.builder.Response parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cc.arduino.builder.Response parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cc.arduino.builder.Response parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cc.arduino.builder.Response parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cc.arduino.builder.Response parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cc.arduino.builder.Response parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cc.arduino.builder.Response parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cc.arduino.builder.Response prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code proto.Response} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:proto.Response) + cc.arduino.builder.ResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cc.arduino.builder.BuilderProto.internal_static_proto_Response_descriptor; + } + + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cc.arduino.builder.BuilderProto.internal_static_proto_Response_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cc.arduino.builder.Response.class, cc.arduino.builder.Response.Builder.class); + } + + // Construct using cc.arduino.builder.Response.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + public Builder clear() { + super.clear(); + line_ = ""; + + return this; + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cc.arduino.builder.BuilderProto.internal_static_proto_Response_descriptor; + } + + public cc.arduino.builder.Response getDefaultInstanceForType() { + return cc.arduino.builder.Response.getDefaultInstance(); + } + + public cc.arduino.builder.Response build() { + cc.arduino.builder.Response result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public cc.arduino.builder.Response buildPartial() { + cc.arduino.builder.Response result = new cc.arduino.builder.Response(this); + result.line_ = line_; + onBuilt(); + return result; + } + + public Builder clone() { + return (Builder) super.clone(); + } + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return (Builder) super.setField(field, value); + } + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return (Builder) super.clearField(field); + } + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return (Builder) super.clearOneof(oneof); + } + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, Object value) { + return (Builder) super.setRepeatedField(field, index, value); + } + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + Object value) { + return (Builder) super.addRepeatedField(field, value); + } + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cc.arduino.builder.Response) { + return mergeFrom((cc.arduino.builder.Response)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cc.arduino.builder.Response other) { + if (other == cc.arduino.builder.Response.getDefaultInstance()) return this; + if (!other.getLine().isEmpty()) { + line_ = other.line_; + onChanged(); + } + onChanged(); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + cc.arduino.builder.Response parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (cc.arduino.builder.Response) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private java.lang.Object line_ = ""; + /** + * optional string line = 1; + */ + public java.lang.String getLine() { + java.lang.Object ref = line_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + line_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string line = 1; + */ + public com.google.protobuf.ByteString + getLineBytes() { + java.lang.Object ref = line_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + line_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string line = 1; + */ + public Builder setLine( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + line_ = value; + onChanged(); + return this; + } + /** + * optional string line = 1; + */ + public Builder clearLine() { + + line_ = getDefaultInstance().getLine(); + onChanged(); + return this; + } + /** + * optional string line = 1; + */ + public Builder setLineBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + line_ = value; + onChanged(); + return this; + } + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return this; + } + + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return this; + } + + + // @@protoc_insertion_point(builder_scope:proto.Response) + } + + // @@protoc_insertion_point(class_scope:proto.Response) + private static final cc.arduino.builder.Response DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cc.arduino.builder.Response(); + } + + public static cc.arduino.builder.Response getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + public Response parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new Response(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + public cc.arduino.builder.Response getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + +} + diff --git a/arduino-core/src/cc/arduino/builder/ResponseOrBuilder.java b/arduino-core/src/cc/arduino/builder/ResponseOrBuilder.java new file mode 100644 index 00000000000..3e77c03bde5 --- /dev/null +++ b/arduino-core/src/cc/arduino/builder/ResponseOrBuilder.java @@ -0,0 +1,19 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: builder.proto + +package cc.arduino.builder; + +public interface ResponseOrBuilder extends + // @@protoc_insertion_point(interface_extends:proto.Response) + com.google.protobuf.MessageOrBuilder { + + /** + * optional string line = 1; + */ + java.lang.String getLine(); + /** + * optional string line = 1; + */ + com.google.protobuf.ByteString + getLineBytes(); +} diff --git a/arduino-core/src/cc/arduino/packages/DiscoveryManager.java b/arduino-core/src/cc/arduino/packages/DiscoveryManager.java index 21876ffc47e..b8c4573aa3b 100644 --- a/arduino-core/src/cc/arduino/packages/DiscoveryManager.java +++ b/arduino-core/src/cc/arduino/packages/DiscoveryManager.java @@ -58,8 +58,8 @@ public DiscoveryManager(Map packages) { // this.packages = packages; discoverers = new ArrayList<>(); - discoverers.add(serialDiscoverer); - discoverers.add(networkDiscoverer); + //discoverers.add(serialDiscoverer); + //discoverers.add(networkDiscoverer); // Search for discoveries in installed packages for (TargetPackage targetPackage : packages.values()) { diff --git a/arduino-core/src/processing/app/BaseNoGui.java b/arduino-core/src/processing/app/BaseNoGui.java index c47a82d69b8..b893aa0434b 100644 --- a/arduino-core/src/processing/app/BaseNoGui.java +++ b/arduino-core/src/processing/app/BaseNoGui.java @@ -1,5 +1,31 @@ package processing.app; +import static processing.app.I18n.tr; +import static processing.app.helpers.filefilters.OnlyDirs.ONLY_DIRS; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; + +import org.apache.commons.compress.utils.IOUtils; +import org.apache.commons.logging.impl.LogFactoryImpl; +import org.apache.commons.logging.impl.NoOpLog; + +import com.fasterxml.jackson.core.JsonProcessingException; + import cc.arduino.Constants; import cc.arduino.contributions.GPGDetachedSignatureVerifier; import cc.arduino.contributions.VersionComparator; @@ -7,13 +33,21 @@ import cc.arduino.contributions.packages.ContributedPlatform; import cc.arduino.contributions.packages.ContributedTool; import cc.arduino.contributions.packages.ContributionsIndexer; +import cc.arduino.files.DeleteFilesOnShutdown; +import cc.arduino.packages.BoardPort; import cc.arduino.packages.DiscoveryManager; -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.*; -import processing.app.helpers.*; +import processing.app.debug.LegacyTargetPackage; +import processing.app.debug.LegacyTargetPlatform; +import processing.app.debug.TargetBoard; +import processing.app.debug.TargetPackage; +import processing.app.debug.TargetPlatform; +import processing.app.debug.TargetPlatformException; +import processing.app.helpers.BasicUserNotifier; +import processing.app.helpers.CommandlineParser; +import processing.app.helpers.FileUtils; +import processing.app.helpers.OSUtils; +import processing.app.helpers.PreferencesMap; +import processing.app.helpers.UserNotifier; import processing.app.helpers.filefilters.OnlyDirs; import processing.app.helpers.filefilters.OnlyFilesWithExtension; import processing.app.legacy.PApplet; @@ -41,9 +75,9 @@ public class BaseNoGui { /** Version string to be used for build */ - public static final int REVISION = 10813; + public static final int REVISION = 10900; /** Extended version string displayed on GUI */ - public static final String VERSION_NAME = "1.8.13"; + public static final String VERSION_NAME = "1.9.0-beta"; public static final String VERSION_NAME_LONG; // Current directory to use for relative paths specified on the @@ -242,6 +276,22 @@ static public File getHardwareFolder() { return getContentFile("hardware"); } + static public List getAllHardwareFolders() { + List res = new ArrayList<>(); + res.add(getHardwareFolder()); + res.add(new File(getSettingsFolder(), "packages")); + res.add(getSketchbookHardwareFolder()); + return res.stream().filter(x -> x.isDirectory()).collect(Collectors.toList()); + } + + static public List getAllToolsFolders() { + List res = new ArrayList<>(); + res.add(BaseNoGui.getContentFile("tools-builder")); + res.add(new File(new File(BaseNoGui.getHardwareFolder(), "tools"), "avr")); + res.add(new File(getSettingsFolder(), "packages")); + return res.stream().filter(x -> x.isDirectory()).collect(Collectors.toList()); + } + static public String getHardwarePath() { return getHardwareFolder().getAbsolutePath(); } @@ -916,6 +966,12 @@ static public void saveFile(String str, File file) throws IOException { } } + static private LinkedList recentlyUsedBoards = new LinkedList(); + + static public LinkedList getRecentlyUsedBoards() { + return recentlyUsedBoards; + } + static public void selectBoard(TargetBoard targetBoard) { TargetPlatform targetPlatform = targetBoard.getContainerPlatform(); TargetPackage targetPackage = targetPlatform.getContainerPackage(); @@ -927,6 +983,13 @@ static public void selectBoard(TargetBoard targetBoard) { File platformFolder = targetPlatform.getFolder(); PreferencesData.set("runtime.platform.path", platformFolder.getAbsolutePath()); PreferencesData.set("runtime.hardware.path", platformFolder.getParentFile().getAbsolutePath()); + + if (!recentlyUsedBoards.contains(targetBoard)) { + recentlyUsedBoards.add(targetBoard); + } + if (recentlyUsedBoards.size() > PreferencesData.getInteger("editor.recent_boards.size", 4)) { + recentlyUsedBoards.remove(); + } } public static void selectSerialPort(String port) { diff --git a/arduino-core/src/processing/app/SketchFile.java b/arduino-core/src/processing/app/SketchFile.java index f1341653b57..35682da60e0 100644 --- a/arduino-core/src/processing/app/SketchFile.java +++ b/arduino-core/src/processing/app/SketchFile.java @@ -246,7 +246,7 @@ public boolean isModified() { public boolean equals(Object o) { return (o instanceof SketchFile) && file.equals(((SketchFile) o).file); } - + /** * Load this piece of code from a file and return the contents. This * completely ignores any changes in the linked storage, if any, and diff --git a/arduino-core/src/processing/app/windows/Platform.java b/arduino-core/src/processing/app/windows/Platform.java index 6d344444f15..95666d3b6ac 100644 --- a/arduino-core/src/processing/app/windows/Platform.java +++ b/arduino-core/src/processing/app/windows/Platform.java @@ -213,6 +213,8 @@ public List preUninstallScripts(File folder) { } public void symlink(File something, File somewhere) throws IOException, InterruptedException { + Process process = Runtime.getRuntime().exec(new String[]{"mklink", somewhere.getAbsolutePath(), something.toString()}, null, somewhere.getParentFile()); + process.waitFor(); } @Override diff --git a/build/arduino-builder-linux64-1.3.25-prepr-rc1.tar.bz2.sha b/build/arduino-builder-linux64-1.3.25-prepr-rc1.tar.bz2.sha new file mode 100644 index 00000000000..ffb12d4f792 --- /dev/null +++ b/build/arduino-builder-linux64-1.3.25-prepr-rc1.tar.bz2.sha @@ -0,0 +1 @@ +5a752dc23ea0d5ebbc60547ea89e69491536c02d diff --git a/build/arduino-cli-0.3.4-alpha.preview-linux32.tar.bz2.sha b/build/arduino-cli-0.3.4-alpha.preview-linux32.tar.bz2.sha new file mode 100644 index 00000000000..d1c9006cd5e --- /dev/null +++ b/build/arduino-cli-0.3.4-alpha.preview-linux32.tar.bz2.sha @@ -0,0 +1 @@ +18f6669f8a3c328f6a096eb6709a2c1e4c9cdeae diff --git a/build/arduino-cli-0.3.4-alpha.preview-linux64.tar.bz2.sha b/build/arduino-cli-0.3.4-alpha.preview-linux64.tar.bz2.sha new file mode 100644 index 00000000000..44b29c7491d --- /dev/null +++ b/build/arduino-cli-0.3.4-alpha.preview-linux64.tar.bz2.sha @@ -0,0 +1 @@ +1309e3bf1685ec5cefbb46cb6397e7c452ac293a diff --git a/build/arduino-cli-0.3.4-alpha.preview-linuxaarch64.tar.bz2.sha b/build/arduino-cli-0.3.4-alpha.preview-linuxaarch64.tar.bz2.sha new file mode 100644 index 00000000000..461d58a95c0 --- /dev/null +++ b/build/arduino-cli-0.3.4-alpha.preview-linuxaarch64.tar.bz2.sha @@ -0,0 +1 @@ +2fd4bd6f4c196e45fa08bb1b6eae27494378708a diff --git a/build/arduino-cli-0.3.4-alpha.preview-linuxarm.tar.bz2.sha b/build/arduino-cli-0.3.4-alpha.preview-linuxarm.tar.bz2.sha new file mode 100644 index 00000000000..52bc08c06d6 --- /dev/null +++ b/build/arduino-cli-0.3.4-alpha.preview-linuxarm.tar.bz2.sha @@ -0,0 +1 @@ +a4977a3dffb2268eee3328bfa362aa31e8bfbbe9 diff --git a/build/arduino-cli-0.3.4-alpha.preview-macosx.tar.bz2.sha b/build/arduino-cli-0.3.4-alpha.preview-macosx.tar.bz2.sha new file mode 100644 index 00000000000..d1004f25ae4 --- /dev/null +++ b/build/arduino-cli-0.3.4-alpha.preview-macosx.tar.bz2.sha @@ -0,0 +1 @@ +47f1beae490e214d2cbde36089fe45e91cc4bd21 diff --git a/build/arduino-cli-0.3.4-alpha.preview-windows.zip.sha b/build/arduino-cli-0.3.4-alpha.preview-windows.zip.sha new file mode 100644 index 00000000000..01eacd79bf1 --- /dev/null +++ b/build/arduino-cli-0.3.4-alpha.preview-windows.zip.sha @@ -0,0 +1 @@ +30d454fb2d76bf08dd40f61414b809f3538a8d31 diff --git a/build/build.xml b/build/build.xml index 6ddec060203..72ef2461620 100644 --- a/build/build.xml +++ b/build/build.xml @@ -101,10 +101,13 @@ + + + @@ -207,6 +210,11 @@ + + + + + @@ -487,8 +495,27 @@ + + + + + + + + + + + + + + + + + + + @@ -678,6 +705,24 @@ + + + + + + + + + + + + + + + + + + @@ -703,6 +748,24 @@ + + + + + + + + + + + + + + + + + + @@ -711,6 +774,7 @@ + @@ -745,6 +809,25 @@ + + + + + + + + + + + + + + + + + + + @@ -753,6 +836,7 @@ + @@ -771,6 +855,7 @@ + @@ -789,6 +874,7 @@ + @@ -837,6 +923,20 @@ + + + + + + + + + + + + + + @@ -1065,6 +1165,28 @@ + + + + + + + + + + + + + + + + + + + + + + @@ -1086,12 +1208,27 @@ + + + + + + + + + + + + + + + diff --git a/build/build_all_dist.bash b/build/build_all_dist.bash index 65e67a743b8..c1dfacdb6e9 100755 --- a/build/build_all_dist.bash +++ b/build/build_all_dist.bash @@ -6,12 +6,12 @@ cd $DIR rm -f ../arduino-*.tar.xz rm -f ../arduino-*.zip -ant -Djava.net.preferIPv4Stack=true -Dplatform=linux32 $@ clean dist -mv linux/arduino-*-linux32.tar.xz ../ - ant -Djava.net.preferIPv4Stack=true -Dplatform=linux64 $@ clean dist mv linux/arduino-*-linux64.tar.xz ../ +ant -Djava.net.preferIPv4Stack=true -Dplatform=linux32 $@ clean dist +mv linux/arduino-*-linux32.tar.xz ../ + ant -Djava.net.preferIPv4Stack=true -Dplatform=linuxarm $@ clean dist mv linux/arduino-*-linuxarm.tar.xz ../ diff --git a/build/macosx/processing.icns b/build/macosx/processing.icns index 070a51fce07..55a286484b4 100644 Binary files a/build/macosx/processing.icns and b/build/macosx/processing.icns differ diff --git a/build/mdns-discovery-0.0.1.zip.sha b/build/mdns-discovery-0.0.1.zip.sha new file mode 100644 index 00000000000..3a25599d01d --- /dev/null +++ b/build/mdns-discovery-0.0.1.zip.sha @@ -0,0 +1 @@ +11ac3c2f9313e1979e3488ab674fabd0884ec0b4 diff --git a/build/serial-discovery-0.0.3.zip.sha b/build/serial-discovery-0.0.3.zip.sha new file mode 100644 index 00000000000..09f6c562fb7 --- /dev/null +++ b/build/serial-discovery-0.0.3.zip.sha @@ -0,0 +1 @@ +f9f0706dd7f327eb92cc0225f58b34677e709152 diff --git a/build/shared/discoverers/disco/boards.txt b/build/shared/discoverers/disco/boards.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/build/shared/discoverers/disco/platform.txt b/build/shared/discoverers/disco/platform.txt new file mode 100644 index 00000000000..f488dc0a066 --- /dev/null +++ b/build/shared/discoverers/disco/platform.txt @@ -0,0 +1,2 @@ +discovery.serial.pattern={runtime.ide.path}/tools/serial-discovery +discovery.mdns.pattern={runtime.ide.path}/tools/mdns-discovery diff --git a/build/shared/examples/09.USB/Mouse/JoystickMouseControl/JoystickMouseControl.ino b/build/shared/examples/09.USB/Mouse/JoystickMouseControl/JoystickMouseControl.ino index aa608f870b1..87164e7d22a 100644 --- a/build/shared/examples/09.USB/Mouse/JoystickMouseControl/JoystickMouseControl.ino +++ b/build/shared/examples/09.USB/Mouse/JoystickMouseControl/JoystickMouseControl.ino @@ -69,8 +69,8 @@ void loop() { lastSwitchState = switchState; // read and scale the two axes: - int xReading = readAxis(A0); - int yReading = readAxis(A1); + int xReading = readAxis(xAxis); + int yReading = readAxis(yAxis); // if the mouse control state is active, move the mouse: if (mouseIsActive) { diff --git a/build/shared/icons/128x128/apps/arduino.png b/build/shared/icons/128x128/apps/arduino.png index 1cdfb28699b..2b3f66bfbf1 100644 Binary files a/build/shared/icons/128x128/apps/arduino.png and b/build/shared/icons/128x128/apps/arduino.png differ diff --git a/build/shared/icons/16x16/apps/arduino.png b/build/shared/icons/16x16/apps/arduino.png index 2f33f429bdf..76bfe5e3955 100644 Binary files a/build/shared/icons/16x16/apps/arduino.png and b/build/shared/icons/16x16/apps/arduino.png differ diff --git a/build/shared/icons/24x24/apps/arduino.png b/build/shared/icons/24x24/apps/arduino.png index 0a4b3952cb1..6bd50d781dd 100644 Binary files a/build/shared/icons/24x24/apps/arduino.png and b/build/shared/icons/24x24/apps/arduino.png differ diff --git a/build/shared/icons/256x256/apps/arduino.png b/build/shared/icons/256x256/apps/arduino.png index 6df847b035a..c2306783148 100644 Binary files a/build/shared/icons/256x256/apps/arduino.png and b/build/shared/icons/256x256/apps/arduino.png differ diff --git a/build/shared/icons/32x32/apps/arduino.png b/build/shared/icons/32x32/apps/arduino.png index c51d0be6450..425edd5fc0c 100644 Binary files a/build/shared/icons/32x32/apps/arduino.png and b/build/shared/icons/32x32/apps/arduino.png differ diff --git a/build/shared/icons/48x48/apps/arduino.png b/build/shared/icons/48x48/apps/arduino.png index 5a91c8eedd0..ce239f3af2a 100644 Binary files a/build/shared/icons/48x48/apps/arduino.png and b/build/shared/icons/48x48/apps/arduino.png differ diff --git a/build/shared/icons/64x64/apps/arduino.png b/build/shared/icons/64x64/apps/arduino.png index 48d578599c1..97fac9553e3 100644 Binary files a/build/shared/icons/64x64/apps/arduino.png and b/build/shared/icons/64x64/apps/arduino.png differ diff --git a/build/shared/icons/72x72/apps/arduino.png b/build/shared/icons/72x72/apps/arduino.png index 3d380c48acb..36d8f91f136 100644 Binary files a/build/shared/icons/72x72/apps/arduino.png and b/build/shared/icons/72x72/apps/arduino.png differ diff --git a/build/shared/icons/96x96/apps/arduino.png b/build/shared/icons/96x96/apps/arduino.png index 82c095468e7..c49ae3e2720 100644 Binary files a/build/shared/icons/96x96/apps/arduino.png and b/build/shared/icons/96x96/apps/arduino.png differ diff --git a/build/shared/lib/about.png b/build/shared/lib/about.png index 71cc20a417a..9436ef0644a 100644 Binary files a/build/shared/lib/about.png and b/build/shared/lib/about.png differ diff --git a/build/shared/lib/about@2x.png b/build/shared/lib/about@2x.png index 017d0815372..1fd46b70ce9 100644 Binary files a/build/shared/lib/about@2x.png and b/build/shared/lib/about@2x.png differ diff --git a/build/shared/lib/arduino.png b/build/shared/lib/arduino.png index 28fa03ab7f7..f5f04e8b5ec 100644 Binary files a/build/shared/lib/arduino.png and b/build/shared/lib/arduino.png differ diff --git a/build/shared/lib/arduino_icon.ico b/build/shared/lib/arduino_icon.ico index a9f3a7acbe5..6df734fa8ad 100644 Binary files a/build/shared/lib/arduino_icon.ico and b/build/shared/lib/arduino_icon.ico differ diff --git a/build/shared/lib/splash.bmp b/build/shared/lib/splash.bmp index a3148785081..cb9b0636594 100644 Binary files a/build/shared/lib/splash.bmp and b/build/shared/lib/splash.bmp differ diff --git a/build/shared/lib/splash.png b/build/shared/lib/splash.png index ba5902107d8..4fd166c19e7 100644 Binary files a/build/shared/lib/splash.png and b/build/shared/lib/splash.png differ diff --git a/build/windows/launcher/application.ico b/build/windows/launcher/application.ico index 1db9b9f4ee3..6df734fa8ad 100644 Binary files a/build/windows/launcher/application.ico and b/build/windows/launcher/application.ico differ diff --git a/build/windows/launcher/config.xml b/build/windows/launcher/config.xml index affef023c77..82d0d9b73eb 100644 --- a/build/windows/launcher/config.xml +++ b/build/windows/launcher/config.xml @@ -37,6 +37,21 @@ %EXEDIR%/lib/commons-logging-1.0.4.jar %EXEDIR%/lib/commons-net-3.3.jar %EXEDIR%/lib/commons-io-2.6.jar + %EXEDIR%/lib/grpc-auth-1.6.1.jar + %EXEDIR%/lib/grpc-context-1.6.1.jar + %EXEDIR%/lib/grpc-core-1.6.1.jar + %EXEDIR%/lib/grpc-grpclb-1.6.1.jar + %EXEDIR%/lib/grpc-netty-1.6.1.jar + %EXEDIR%/lib/grpc-okhttp-1.6.1.jar + %EXEDIR%/lib/grpc-protobuf-1.6.1.jar + %EXEDIR%/lib/grpc-protobuf-lite-1.6.1.jar + %EXEDIR%/lib/grpc-protobuf-nano-1.6.1.jar + %EXEDIR%/lib/grpc-services-1.6.1.jar + %EXEDIR%/lib/grpc-stub-1.6.1.jar + %EXEDIR%/lib/guava-19.0.jar + %EXEDIR%/lib/instrumentation-api-0.4.3.jar + %EXEDIR%/lib/protobuf-java-3.4.0.jar + %EXEDIR%/lib/netty-all-4.1.15.Final.jar %EXEDIR%/lib/jackson-annotations-2.9.5.jar %EXEDIR%/lib/jackson-core-2.9.5.jar %EXEDIR%/lib/jackson-databind-2.9.5.jar @@ -53,6 +68,7 @@ %EXEDIR%/lib/jssc-2.8.0-arduino4.jar %EXEDIR%/lib/pde.jar %EXEDIR%/lib/rsyntaxtextarea-3.0.3-SNAPSHOT.jar + %EXEDIR%/lib/autocomplete-2.6.1.jar %EXEDIR%/lib/xml-apis-1.3.04.jar %EXEDIR%/lib/xml-apis-ext-1.3.04.jar %EXEDIR%/lib/xmlgraphics-commons-2.0.jar diff --git a/build/windows/launcher/config_debug.xml b/build/windows/launcher/config_debug.xml index 59d5a35ae0a..8de301563eb 100644 --- a/build/windows/launcher/config_debug.xml +++ b/build/windows/launcher/config_debug.xml @@ -37,6 +37,21 @@ %EXEDIR%/lib/commons-logging-1.0.4.jar %EXEDIR%/lib/commons-net-3.3.jar %EXEDIR%/lib/commons-io-2.6.jar + %EXEDIR%/lib/grpc-auth-1.6.1.jar + %EXEDIR%/lib/grpc-context-1.6.1.jar + %EXEDIR%/lib/grpc-core-1.6.1.jar + %EXEDIR%/lib/grpc-grpclb-1.6.1.jar + %EXEDIR%/lib/grpc-netty-1.6.1.jar + %EXEDIR%/lib/grpc-okhttp-1.6.1.jar + %EXEDIR%/lib/grpc-protobuf-1.6.1.jar + %EXEDIR%/lib/grpc-protobuf-lite-1.6.1.jar + %EXEDIR%/lib/grpc-protobuf-nano-1.6.1.jar + %EXEDIR%/lib/grpc-services-1.6.1.jar + %EXEDIR%/lib/grpc-stub-1.6.1.jar + %EXEDIR%/lib/guava-19.0.jar + %EXEDIR%/lib/instrumentation-api-0.4.3.jar + %EXEDIR%/lib/protobuf-java-3.4.0.jar + %EXEDIR%/lib/netty-all-4.1.15.Final.jar %EXEDIR%/lib/jackson-annotations-2.9.5.jar %EXEDIR%/lib/jackson-core-2.9.5.jar %EXEDIR%/lib/jackson-databind-2.9.5.jar @@ -53,6 +68,7 @@ %EXEDIR%/lib/jssc-2.8.0-arduino4.jar %EXEDIR%/lib/pde.jar %EXEDIR%/lib/rsyntaxtextarea-3.0.3-SNAPSHOT.jar + %EXEDIR%/lib/autocomplete-2.6.1.jar %EXEDIR%/lib/xml-apis-1.3.04.jar %EXEDIR%/lib/xml-apis-ext-1.3.04.jar %EXEDIR%/lib/xmlgraphics-commons-2.0.jar