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 pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy