mbien commented on code in PR #7618: URL: https://github.com/apache/netbeans/pull/7618#discussion_r1759608531
########## php/php.blade/src/org/netbeans/modules/php/blade/editor/completion/BladeCompletionItem.java: ########## @@ -0,0 +1,363 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.php.blade.editor.completion; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.event.KeyEvent; +import javax.swing.ImageIcon; +import javax.swing.text.BadLocationException; +import javax.swing.text.Caret; +import javax.swing.text.JTextComponent; +import org.netbeans.api.annotations.common.NullAllowed; +import org.netbeans.api.editor.completion.Completion; +import org.netbeans.editor.BaseDocument; +import org.netbeans.lib.editor.codetemplates.api.CodeTemplateManager; +import org.netbeans.modules.php.blade.editor.ResourceUtilities; +import org.netbeans.modules.php.blade.syntax.BladeDirectivesUtils; +import org.netbeans.spi.editor.completion.CompletionItem; +import org.netbeans.spi.editor.completion.CompletionTask; +import org.netbeans.spi.editor.completion.support.CompletionUtilities; +import org.openide.util.ImageUtilities; + +/** + * + * @author bhaidu + */ +public abstract class BladeCompletionItem implements CompletionItem { + + protected static final int DEFAULT_SORT_PRIORITY = 20; + private final int substitutionOffset; + private final String name; + @NullAllowed + private final String description; + private boolean shift; + + BladeCompletionItem(String name, int substitutionOffset, String description) { + this.name = name; + this.substitutionOffset = substitutionOffset; + this.description = description; + } + + public String getName() { + return this.name; + } + + public String getDescription() { + return this.description; + } + + @Override + public void defaultAction(JTextComponent component) { + if (component != null) { + if (!shift) { + Completion.get().hideDocumentation(); + Completion.get().hideCompletion(); + } + int caretOffset = component.getSelectionEnd(); + int len = caretOffset - substitutionOffset; + if (len >= 0) { + substituteText(component, len); + } + } + } + + @Override + public void processKeyEvent(KeyEvent e) { + shift = (e.getKeyCode() == KeyEvent.VK_ENTER && e.getID() == KeyEvent.KEY_PRESSED && e.isShiftDown()); + } + + @Override + public int getPreferredWidth(Graphics grphcs, Font font) { + return CompletionUtilities.getPreferredWidth(getLeftHtmlText(), getRightHtmlText(), grphcs, font); + } + + @Override + public void render(Graphics g, Font defaultFont, Color defaultColor, Color backgroundColor, int width, int height, boolean selected) { + CompletionUtilities.renderHtml(getIcon(), getLeftHtmlText(), getRightHtmlText(), g, defaultFont, defaultColor, width, height, selected); + } + + + @Override + public CompletionTask createDocumentationTask() { + return null; + } + + @Override + public CompletionTask createToolTipTask() { + return null; + } + + @Override + public boolean instantSubstitution(JTextComponent component) { + if (component != null) { + try { + int caretOffset = component.getSelectionEnd(); + if (caretOffset > substitutionOffset) { + String currentText = component.getDocument().getText(substitutionOffset, caretOffset - substitutionOffset); + if (!getSubstituteText().startsWith(currentText)) { + return false; + } + } + } catch (BadLocationException ble) { + } + } + defaultAction(component); + return true; + } + + @Override + public int getSortPriority() { + return DEFAULT_SORT_PRIORITY; + } + + @Override + public CharSequence getSortText() { + return getItemText(); + } + + @Override + public CharSequence getInsertPrefix() { + return getItemText(); + } + + protected ImageIcon getIcon() { + return null; + } + + protected String getLeftHtmlText() { + return name; + } + + protected String getRightHtmlText() { + return null; + } + + protected String getSubstituteText() { + return getItemText(); + } + + public String getItemText() { + return name; + } + + private boolean substituteText(JTextComponent component, int len) { + return substituteText(component, getSubstituteText(), len, 0); + } + + private boolean substituteText(JTextComponent c, final String substituteText, final int len, int moveBack) { + final BaseDocument doc = (BaseDocument) c.getDocument(); + final boolean[] result = new boolean[1]; + result[0] = true; + + doc.runAtomic(new Runnable() { + @Override + public void run() { + try { + //test whether we are trying to insert sg. what is already present in the text + String currentText = doc.getText(substitutionOffset, (doc.getLength() - substitutionOffset) < substituteText.length() ? (doc.getLength() - substitutionOffset) : substituteText.length()); + if (!substituteText.equals(currentText)) { + //remove common part + doc.remove(substitutionOffset, len); + insertString(doc, substitutionOffset, substituteText, c); + } else { + c.setCaretPosition(c.getSelectionEnd() + substituteText.length() - len); + } + } catch (BadLocationException ex) { + result[0] = false; + } + + } + }); + + //format the inserted text + reindent(c); + + if (moveBack != 0) { + Caret caret = c.getCaret(); + int dot = caret.getDot(); + caret.setDot(dot - moveBack); + } + + return result[0]; + } + + protected void insertString(BaseDocument doc, int substitutionOffset, + String substituteText, JTextComponent c) throws BadLocationException { + doc.insertString(substitutionOffset, substituteText, null); + } + + protected void reindent(JTextComponent c) { + + } + + public static class BladeTag extends BladeCompletionItem { + + public BladeTag(String name, int substitutionOffset) { + super(name, substitutionOffset, null); + } + } + + public static class InlineDirective extends BladeCompletionItem { + + public InlineDirective(String directive, int substitutionOffset, + String description) { + super(directive, substitutionOffset, description); + } + + @Override + protected String getRightHtmlText() { + return getDescription(); + } + + @Override + protected ImageIcon getIcon() { + String path = ResourceUtilities.DIRECTIVE_ICON; + return ImageUtilities.loadImageIcon(path, false); + } + } + + public static class DirectiveWithArg extends InlineDirective { + + public DirectiveWithArg(String directive, int substitutionOffset, + String description) { + super(directive, substitutionOffset, description); + } + + @Override + protected String getSubstituteText() { + String template = getItemText() + "($$${arg})"; // NOI18N + switch (getName()) { + case BladeDirectivesUtils.DIRECTIVE_INCLUDE, + BladeDirectivesUtils.DIRECTIVE_EXTENDS -> + template = getItemText() + "('${path}')"; // NOI18N + } + return template; + } + + @Override + protected String getLeftHtmlText() { + return getName() + "()"; // NOI18N + } + + @Override + protected void insertString(BaseDocument doc, int substitutionOffset, + String substituteText, JTextComponent ctx) throws BadLocationException { + ctx.setCaretPosition(substitutionOffset); + CodeTemplateManager.get(doc).createTemporary(substituteText).insert(ctx); + } + } + + public static class BlockDirective extends BladeCompletionItem { + + private final String endTag; + + public BlockDirective(String directive, String endTag, int substitutionOffset, + String description) { + super(directive, substitutionOffset, description); + this.endTag = endTag; + } + + @Override + protected String getSubstituteText() { + return getItemText() + "\n${selection}${cursor}\n" + endTag; // NOI18N + } + + @Override + protected String getLeftHtmlText() { + return getName() + " ... " + endTag; // NOI18N + } + + @Override + protected String getRightHtmlText() { + return getDescription(); + } + + @Override + protected ImageIcon getIcon() { + String path = ResourceUtilities.DIRECTIVE_ICON; + return ImageUtilities.loadImageIcon(path, false); + } + + @Override + protected void insertString(BaseDocument doc, int substitutionOffset, + String substituteText, JTextComponent ctx) throws BadLocationException { + ctx.setCaretPosition(substitutionOffset); + CodeTemplateManager.get(doc).createTemporary(substituteText).insert(ctx); + } + + public String getEndTag() { + return endTag; + } + } + + public static class BlockDirectiveWithArg extends BlockDirective { + + public BlockDirectiveWithArg(String directive, String endTag, int substitutionOffset, String description) { + super(directive, endTag, substitutionOffset, description); + } + + @Override + protected String getSubstituteText() { + String template = getItemText() + "($$${arg})\n\n${selection}${cursor}\n" + getEndTag(); // NOI18N + + switch (getName()) { + case BladeDirectivesUtils.DIRECTIVE_FOREACH -> + template = getItemText() + "($$${array} as $$${item})\n${selection}${cursor}\n" + getEndTag(); // NOI18N + } + + return template; Review Comment: this would build the template string only once: ```java return switch (getName()) { case DIRECTIVE_FOREACH ... default ... }; ``` ########## php/php.blade/src/org/netbeans/modules/php/blade/editor/cache/QueryCache.java: ########## @@ -0,0 +1,111 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.php.blade.editor.cache; + +import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * + * @author bogdan + */ +public final class QueryCache<K, V> { + + public static final Long DEFAULT_CACHE_TIMEOUT = 60000L; + + private Map<K, CacheValue<V>> cacheMap; + private Long cacheTimeout; + + //private static final Map<QuerySupport, QueryCache> QUERY_SUPPORT_INDEX = new WeakHashMap<>(); + + public QueryCache() { + this(DEFAULT_CACHE_TIMEOUT); + } + + public QueryCache(Long cacheTimeout) { + this.cacheTimeout = cacheTimeout; + this.clear(); + } + + public void clean() { + for (K key : this.getExpiredKeys()) { + this.remove(key); + } + } + + public boolean containsKey(K key) { + return this.cacheMap.containsKey(key); + } + + protected Set<K> getExpiredKeys() { + return this.cacheMap.keySet().parallelStream() + .filter(this::isExpired) + .collect(Collectors.toSet()); Review Comment: you sure `parallelStream()` is a good idea here? It always comes with setup and runtime overhead and all this stream does is to filter a set - so the parallel task itself is tiny. I would only recommend using parallel streams if it is also demonstrated in a benchmark that they make a difference in that usecase. ########## php/php.blade/src/org/netbeans/modules/php/blade/editor/embedding/BladeHtmlEmbeddingProvider.java: ########## @@ -0,0 +1,101 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.php.blade.editor.embedding; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.netbeans.api.lexer.Token; +import org.netbeans.api.lexer.TokenHierarchy; +import org.netbeans.api.lexer.TokenId; +import org.netbeans.api.lexer.TokenSequence; +import org.netbeans.modules.parsing.api.Embedding; +import org.netbeans.modules.parsing.api.Snapshot; +import org.netbeans.modules.parsing.spi.EmbeddingProvider; +import org.netbeans.modules.php.blade.editor.BladeLanguage; +import org.netbeans.modules.php.blade.editor.lexer.BladeTokenId; + +/** + * this will enable braces matches of html elements + * + * @author bhaidu + */ [email protected]( + mimeType = BladeLanguage.MIME_TYPE, + targetMimeType = "text/html") +public class BladeHtmlEmbeddingProvider extends EmbeddingProvider { + public static final String FILLER = " "; + public static final String TARGET_MIME_TYPE = "text/html"; //NOI18N + + @Override + public List<Embedding> getEmbeddings(final Snapshot snapshot) { + TokenHierarchy<?> tokenHierarchy = snapshot.getTokenHierarchy(); + TokenSequence<?> sequence = tokenHierarchy.tokenSequence(); + + if (sequence == null || !sequence.isValid()) { + return Collections.emptyList(); + } + sequence.moveStart(); + List<Embedding> embeddings = new ArrayList<>(); + + int offset = 0; + int len = 0; + + String fake; + + try { + while (sequence.moveNext()) { + Token<?> t = sequence.token(); + offset = sequence.offset(); + TokenId id = t.id(); + len += t.length(); + String tText = t.text().toString(); + if (len == 0) { + continue; + } + if (id.equals(BladeTokenId.HTML)) { + embeddings.add(snapshot.create(offset, t.length(), TARGET_MIME_TYPE)); + } else { + fake = new String(new char[tText.length()]).replace("\0", FILLER); + embeddings.add(snapshot.create(fake, TARGET_MIME_TYPE)); + } + } + } catch (Exception ex) { + //Exceptions.printStackTrace(ex); + return Collections.emptyList(); + } Review Comment: if possible catch a more specific exception (or multiple with multicatch). Since this would catch NPEs too which is never good. ########## php/php.blade/src/org/netbeans/modules/php/blade/editor/format/FormatToken.java: ########## @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.php.blade.editor.format; + +/** + * + * @author bhaidu + */ +public class FormatToken { Review Comment: record? ########## php/php.blade/src/org/netbeans/modules/php/blade/editor/directives/CustomDirectives.java: ########## @@ -0,0 +1,302 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.php.blade.editor.directives; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.WeakHashMap; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.netbeans.api.project.Project; +import org.netbeans.modules.csl.api.DeclarationFinder; +import org.netbeans.modules.php.blade.editor.parser.ParsingUtils; +import org.netbeans.modules.php.blade.project.BladeProjectProperties; +import org.netbeans.modules.php.editor.parser.astnodes.Expression; +import org.netbeans.modules.php.editor.parser.astnodes.FunctionInvocation; +import org.netbeans.modules.php.editor.parser.astnodes.Scalar; +import org.openide.filesystems.FileChangeAdapter; +import org.openide.filesystems.FileChangeListener; +import org.openide.filesystems.FileEvent; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; + +/** + * + * @author bhaidu + */ +public final class CustomDirectives { + + private final Project project; + private static final Map<Project, CustomDirectives> INSTANCES = new WeakHashMap<>(); + private final Map<FileObject, List<CustomDirective>> customDirectives = new LinkedHashMap<>(); + + public List<CustomDirective> customDirectiveList = new ArrayList<>(); + + private final FileChangeListener fileChangeListener = new FileChangeListenerImpl(); + + private static final Logger LOGGER = Logger.getLogger(CustomDirectives.class.getName()); + + public static CustomDirectives getInstance(Project project) { + if (project == null) { + return new CustomDirectives(); + } Review Comment: should this throw `IllegalArgumentException` on null project? also note that `BladeProjectProperties` has a similar `getInstance` method which behaves differently, it will store the "null" project as key in the map. ########## php/php.blade/src/org/netbeans/modules/php/blade/editor/indexing/IndexManager.java: ########## @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.php.blade.editor.indexing; + +import java.io.File; +import java.util.Enumeration; +import org.netbeans.api.project.Project; +import org.netbeans.modules.parsing.api.indexing.IndexingManager; +import org.netbeans.modules.php.blade.project.BladeProjectProperties; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; + +/** + * + * @author bogdan + */ +public class IndexManager { + + public static void reindexProjectViews(Project project) { + assert project != null; + String[] views = BladeProjectProperties.getInstance(project).getViewsPathList(); Review Comment: if project is null it should probably do nothing + log a warning, right? ########## php/php.blade/src/org/netbeans/modules/php/blade/editor/lexer/BladeLexerUtils.java: ########## @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.php.blade.editor.lexer; + +import java.util.Arrays; +import java.util.List; +import javax.swing.text.Document; +import org.netbeans.api.lexer.Language; +import org.netbeans.api.lexer.TokenHierarchy; +import org.netbeans.api.lexer.TokenSequence; +import static org.netbeans.modules.php.blade.syntax.antlr4.v10.BladeAntlrLexer.*; +import org.netbeans.modules.php.editor.lexer.PHPTokenId; + +/** + * + * @author bogdan + */ +public final class BladeLexerUtils { + + private BladeLexerUtils() { + + } + + public static final List<Integer> TOKENS_WITH_IDENTIFIABLE_PARAM = Arrays.asList(new Integer[]{ + D_EXTENDS, D_INCLUDE, D_INCLUDE_IF, D_INCLUDE_WHEN, + D_INCLUDE_UNLESS, D_EACH, D_SECTION, D_HAS_SECTION, D_SECTION_MISSING, + D_PUSH, D_PUSH_IF, D_PREPEND, D_USE, D_INJECT, D_ASSET_BUNDLER + }); Review Comment: `List.of` would make this immutable. Should this be a Set? (see other comment) ########## php/php.blade/src/org/netbeans/modules/php/blade/editor/indexing/BladeIndex.java: ########## @@ -0,0 +1,321 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.php.blade.editor.indexing; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.WeakHashMap; +import java.util.concurrent.ExecutionException; +import org.netbeans.api.project.Project; +import org.netbeans.api.project.ui.OpenProjects; +import org.netbeans.modules.csl.api.OffsetRange; +import org.netbeans.modules.parsing.spi.indexing.support.IndexResult; +import org.netbeans.modules.parsing.spi.indexing.support.QuerySupport; +import org.netbeans.modules.php.blade.editor.parser.BladeParserResult.Reference; +import org.openide.filesystems.FileObject; +import org.openide.util.Exceptions; + +/** + * + * @author bhaidu + */ +public class BladeIndex { + + private final QuerySupport querySupport; + private static final Map<Project, BladeIndex> INDEXES = new WeakHashMap<>(); + private static boolean areProjectsOpen = false; + + private BladeIndex(QuerySupport querySupport) throws IOException { + this.querySupport = querySupport; + } + + public QuerySupport getQuerySupport() { + return querySupport; + } + + public static BladeIndex get(Project project) throws IOException { + if (project == null) { + return null; + } + synchronized (INDEXES) { Review Comment: this is the third variant how to handle null projects ;) would be better to pick one and go with it everywhere. I think null projects as param should probably throw `IllegalArgumentException`. ########## php/php.blade/src/org/netbeans/modules/php/blade/editor/ui/customizer/UiOptionsUtils.java: ########## @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.php.blade.editor.ui.customizer; + +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; + + +/** + * + * @author bhaidu + */ +public class UiOptionsUtils { + + public static String encodeToStrings(Enumeration<String> list) { + List<String> result = new ArrayList<>(); + while (list.hasMoreElements()) { + result.add(list.nextElement()); + } + + return String.join("|", result); Review Comment: -> ```java return String.join("|", Collections.list(list)); ``` ########## php/php.blade/src/org/netbeans/modules/php/blade/syntax/antlr4/v10/BladeAntlrUtils.java: ########## @@ -0,0 +1,322 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.php.blade.syntax.antlr4.v10; + +import java.util.List; +import javax.swing.text.BadLocationException; +import javax.swing.text.Document; +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.Token; +import static org.netbeans.modules.php.blade.syntax.antlr4.v10.BladeAntlrParser.*; +import org.netbeans.spi.lexer.antlr4.AntlrTokenSequence; + +/** + * + * @author bogdan + */ +public final class BladeAntlrUtils { + + private BladeAntlrUtils() { + + } + + public static AntlrTokenSequence getTokens(Document doc) { + + try { + String text = doc.getText(0, doc.getLength()); + return new AntlrTokenSequence(new BladeAntlrLexer(CharStreams.fromString(text))); + } catch (BadLocationException ex) { + + } + return null; + } + + public static Token getToken(Document doc, int offset) { + AntlrTokenSequence tokens = getTokens(doc); + if (tokens == null || tokens.isEmpty()) { + return null; + } + + tokens.seekTo(offset); + + if (!tokens.hasNext()) { + return null; + } + + Token token = tokens.next().get(); + + //need to move back + if (token != null && tokens.hasPrevious() && token.getStartIndex() > offset && token.getStopIndex() > offset) { + token = tokens.previous().get(); + } + + return token; + } + + public static Token findForward(Document doc, Token start, + List<String> stopTokenText, List<String> openTokensText) { Review Comment: the `find*` methods in this utility call `contains` on lists. It could be worth checking if this could be sets instead or `Collection`, so that the caller can decide when to pass a List or a Set. ########## php/php.blade/src/org/netbeans/modules/php/blade/editor/components/ComponentElement.java: ########## @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.php.blade.editor.components; + +import java.util.HashSet; +import java.util.Set; + +/** + * TO use in implementation with ComponentModel + * + * @author bhaidu + */ +public class ComponentElement { + public String name; + public String qualifiedClassName; + + public Set<String> properties = new HashSet<>(); Review Comment: this class isn't used anywhere atm, but this looks like a potential candidate for a `record` in case this should stay. ########## php/php.blade/src/org/netbeans/modules/php/blade/editor/completion/BladePhpCompletionProvider.java: ########## @@ -0,0 +1,383 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.php.blade.editor.completion; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.text.BadLocationException; +import javax.swing.text.JTextComponent; +import javax.swing.text.Document; +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.Token; +import org.netbeans.api.editor.document.EditorDocumentUtils; +import org.netbeans.api.editor.mimelookup.MimeRegistration; +import org.netbeans.api.editor.mimelookup.MimeRegistrations; +import org.netbeans.api.project.Project; +import org.netbeans.modules.php.blade.editor.BladeLanguage; +import org.netbeans.modules.php.blade.editor.EditorStringUtils; +import org.netbeans.modules.php.blade.editor.ResourceUtilities; +import org.netbeans.modules.php.blade.editor.indexing.BladeIndex; +import org.netbeans.modules.php.blade.editor.indexing.BladeIndex.IndexedReferenceId; +import org.netbeans.modules.php.blade.editor.path.BladePathUtils; +import org.netbeans.modules.php.blade.project.ProjectUtils; +import org.netbeans.modules.php.blade.syntax.antlr4.v10.BladeAntlrLexer; +import static org.netbeans.modules.php.blade.syntax.antlr4.v10.BladeAntlrLexer.*; +import org.netbeans.modules.php.blade.syntax.antlr4.v10.BladeAntlrUtils; +import org.netbeans.spi.editor.completion.CompletionItem; +import org.netbeans.spi.editor.completion.CompletionProvider; +import org.netbeans.spi.editor.completion.CompletionResultSet; +import org.netbeans.spi.editor.completion.CompletionTask; +import org.netbeans.spi.editor.completion.support.AsyncCompletionQuery; +import org.netbeans.spi.editor.completion.support.AsyncCompletionTask; +import org.netbeans.spi.editor.completion.support.CompletionUtilities; +import org.netbeans.spi.lexer.antlr4.AntlrTokenSequence; +import org.openide.filesystems.FileObject; +import org.openide.util.Exceptions; + +/** + * + * @author bhaidu + */ +@MimeRegistrations(value = { + @MimeRegistration(mimeType = "text/x-php5", service = CompletionProvider.class, position = 102), +} +) +public class BladePhpCompletionProvider implements CompletionProvider { + + private static final Logger LOGGER = Logger.getLogger(BladePhpCompletionProvider.class.getName()); + public static final String JS_ASSET_FOLDER = "resources/js"; // NOI18N + public static final String CSS_ASSET_FOLDER = "resources/css"; // NOI18N + + public enum CompletionType { + BLADE_PATH, + YIELD_ID, + DIRECTIVE, + HTML_COMPONENT_TAG, + FOLDER, + CSS_FILE, + JS_FILE + } + + @Override + public CompletionTask createTask(int queryType, JTextComponent component) { + return new AsyncCompletionTask(new BladeCompletionQuery(), component); + } + + @Override + public int getAutoQueryTypes(JTextComponent component, String typedText) { + FileObject fo = EditorDocumentUtils.getFileObject(component.getDocument()); + if (fo == null || !fo.getMIMEType().equals(BladeLanguage.MIME_TYPE)) { + return 0; + } + + if (typedText.length() == 0) { + return 0; + } + + //don't autocomplete on space, \n, ) + if (typedText.trim().isEmpty()) { + return 0; + } + + char lastChar = typedText.charAt(typedText.length() - 1); + switch (lastChar) { + case ')': + case '\n': + case '<': + case '>': + return 0; + } + + return COMPLETION_QUERY_TYPE; + } + + private class BladeCompletionQuery extends AsyncCompletionQuery { + + public BladeCompletionQuery() { + } + + @Override + protected void query(CompletionResultSet resultSet, Document doc, int caretOffset) { + long startTime = System.currentTimeMillis(); + doQuery(resultSet, doc, caretOffset); + long time = System.currentTimeMillis() - startTime; + if (time > 2000) { + LOGGER.log(Level.INFO, "Slow completion time detected. {0}ms", time); + } + resultSet.finish(); + } + } + + private void doQuery(CompletionResultSet resultSet, Document doc, int caretOffset) { + FileObject fo = EditorDocumentUtils.getFileObject(doc); + + if (fo == null || !fo.getMIMEType().equals(BladeLanguage.MIME_TYPE)) { + return; + } + + AntlrTokenSequence tokens; + try { + String docText = doc.getText(0, doc.getLength()); + tokens = new AntlrTokenSequence(new BladeAntlrLexer(CharStreams.fromString(docText))); + } catch (BadLocationException ex) { + Exceptions.printStackTrace(ex); + return; + } + + if (tokens.isEmpty()) { + return; + } + + if (caretOffset > 1) { + tokens.seekTo(caretOffset - 1); + } else { + tokens.seekTo(caretOffset); + } + + Token currentToken; + + if (!tokens.hasNext() && tokens.hasPrevious()) { + //the carret got too far + currentToken = tokens.previous().get(); + } else if (tokens.hasNext()) { + currentToken = tokens.next().get(); + } else { + return; + } + + if (currentToken == null) { + return; + } + + if (currentToken.getText().trim().length() == 0) { + return; + } + + switch (currentToken.getType()) { + case BL_PARAM_STRING: { + String pathName = EditorStringUtils.stripSurroundingQuotes(currentToken.getText()); + List<Integer> tokensMatch = Arrays.asList(new Integer[]{ + D_EXTENDS, D_INCLUDE, D_SECTION, D_HAS_SECTION, + D_INCLUDE_IF, D_INCLUDE_WHEN, D_INCLUDE_UNLESS, D_INCLUDE_FIRST, + D_EACH, D_PUSH, D_PUSH_IF, D_PREPEND + }); + + List<Integer> tokensStop = Arrays.asList(new Integer[]{HTML, BL_COMMA, BL_PARAM_CONCAT_OPERATOR}); Review Comment: constants and `Set.of()`? ########## php/php.blade/src/org/netbeans/modules/php/blade/editor/embedding/BladePhpEmbeddingProvider.java: ########## @@ -0,0 +1,93 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.php.blade.editor.embedding; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.netbeans.api.lexer.Token; +import org.netbeans.api.lexer.TokenHierarchy; +import org.netbeans.api.lexer.TokenId; +import org.netbeans.api.lexer.TokenSequence; +import org.netbeans.modules.parsing.api.Embedding; +import org.netbeans.modules.parsing.api.Snapshot; +import org.netbeans.modules.parsing.spi.EmbeddingProvider; +import org.netbeans.modules.php.blade.editor.BladeLanguage; +import org.netbeans.modules.php.blade.editor.lexer.BladeTokenId; + +/** + * this will enable braces matches of html elements + * + * @author bhaidu + */ [email protected]( + mimeType = BladeLanguage.MIME_TYPE, + targetMimeType = "text/x-php5") +public class BladePhpEmbeddingProvider extends EmbeddingProvider { + public static final String TARGET_MIME_TYPE = "text/x-php5"; //NOI18N + + @Override + public List<Embedding> getEmbeddings(final Snapshot snapshot) { + TokenHierarchy<?> tokenHierarchy = snapshot.getTokenHierarchy(); + TokenSequence<?> sequence = tokenHierarchy.tokenSequence(); + if (sequence == null) { + return Collections.emptyList(); + } + sequence.moveStart(); + List<Embedding> embeddings = new ArrayList<>(); + + int offset = 0; + int len = 0; + + String fake; + + while (sequence.moveNext()) { + Token<?> t = sequence.token(); + offset = sequence.offset(); + TokenId id = t.id(); + len += t.length(); + String tText = t.text().toString(); + if (len == 0) { + continue; + } + if (id.equals(BladeTokenId.PHP_INLINE)) { + embeddings.add(snapshot.create(offset, t.length(), TARGET_MIME_TYPE)); + } else { + fake = new String(new char[tText.length()]).replace("\0", "@"); + embeddings.add(snapshot.create(fake, TARGET_MIME_TYPE)); + } + } + + if (embeddings.isEmpty()) { + return Collections.singletonList(snapshot.create("", TARGET_MIME_TYPE)); + } else { + return Collections.singletonList(Embedding.create(embeddings)); + } Review Comment: same here ########## php/php.blade/src/org/netbeans/modules/php/blade/editor/completion/BladeCompletionItem.java: ########## @@ -0,0 +1,363 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.php.blade.editor.completion; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.event.KeyEvent; +import javax.swing.ImageIcon; +import javax.swing.text.BadLocationException; +import javax.swing.text.Caret; +import javax.swing.text.JTextComponent; +import org.netbeans.api.annotations.common.NullAllowed; +import org.netbeans.api.editor.completion.Completion; +import org.netbeans.editor.BaseDocument; +import org.netbeans.lib.editor.codetemplates.api.CodeTemplateManager; +import org.netbeans.modules.php.blade.editor.ResourceUtilities; +import org.netbeans.modules.php.blade.syntax.BladeDirectivesUtils; +import org.netbeans.spi.editor.completion.CompletionItem; +import org.netbeans.spi.editor.completion.CompletionTask; +import org.netbeans.spi.editor.completion.support.CompletionUtilities; +import org.openide.util.ImageUtilities; + +/** + * + * @author bhaidu + */ +public abstract class BladeCompletionItem implements CompletionItem { + + protected static final int DEFAULT_SORT_PRIORITY = 20; + private final int substitutionOffset; + private final String name; + @NullAllowed + private final String description; + private boolean shift; + + BladeCompletionItem(String name, int substitutionOffset, String description) { + this.name = name; + this.substitutionOffset = substitutionOffset; + this.description = description; + } + + public String getName() { + return this.name; + } + + public String getDescription() { + return this.description; + } + + @Override + public void defaultAction(JTextComponent component) { + if (component != null) { + if (!shift) { + Completion.get().hideDocumentation(); + Completion.get().hideCompletion(); + } + int caretOffset = component.getSelectionEnd(); + int len = caretOffset - substitutionOffset; + if (len >= 0) { + substituteText(component, len); + } + } + } + + @Override + public void processKeyEvent(KeyEvent e) { + shift = (e.getKeyCode() == KeyEvent.VK_ENTER && e.getID() == KeyEvent.KEY_PRESSED && e.isShiftDown()); + } + + @Override + public int getPreferredWidth(Graphics grphcs, Font font) { + return CompletionUtilities.getPreferredWidth(getLeftHtmlText(), getRightHtmlText(), grphcs, font); + } + + @Override + public void render(Graphics g, Font defaultFont, Color defaultColor, Color backgroundColor, int width, int height, boolean selected) { + CompletionUtilities.renderHtml(getIcon(), getLeftHtmlText(), getRightHtmlText(), g, defaultFont, defaultColor, width, height, selected); + } + + + @Override + public CompletionTask createDocumentationTask() { + return null; + } + + @Override + public CompletionTask createToolTipTask() { + return null; + } + + @Override + public boolean instantSubstitution(JTextComponent component) { + if (component != null) { + try { + int caretOffset = component.getSelectionEnd(); + if (caretOffset > substitutionOffset) { + String currentText = component.getDocument().getText(substitutionOffset, caretOffset - substitutionOffset); + if (!getSubstituteText().startsWith(currentText)) { + return false; + } + } + } catch (BadLocationException ble) { + } + } + defaultAction(component); + return true; + } + + @Override + public int getSortPriority() { + return DEFAULT_SORT_PRIORITY; + } + + @Override + public CharSequence getSortText() { + return getItemText(); + } + + @Override + public CharSequence getInsertPrefix() { + return getItemText(); + } + + protected ImageIcon getIcon() { + return null; + } + + protected String getLeftHtmlText() { + return name; + } + + protected String getRightHtmlText() { + return null; + } + + protected String getSubstituteText() { + return getItemText(); + } + + public String getItemText() { + return name; + } + + private boolean substituteText(JTextComponent component, int len) { + return substituteText(component, getSubstituteText(), len, 0); + } + + private boolean substituteText(JTextComponent c, final String substituteText, final int len, int moveBack) { + final BaseDocument doc = (BaseDocument) c.getDocument(); + final boolean[] result = new boolean[1]; + result[0] = true; + + doc.runAtomic(new Runnable() { + @Override + public void run() { + try { + //test whether we are trying to insert sg. what is already present in the text + String currentText = doc.getText(substitutionOffset, (doc.getLength() - substitutionOffset) < substituteText.length() ? (doc.getLength() - substitutionOffset) : substituteText.length()); + if (!substituteText.equals(currentText)) { + //remove common part + doc.remove(substitutionOffset, len); + insertString(doc, substitutionOffset, substituteText, c); + } else { + c.setCaretPosition(c.getSelectionEnd() + substituteText.length() - len); + } + } catch (BadLocationException ex) { + result[0] = false; + } + + } + }); + + //format the inserted text + reindent(c); + + if (moveBack != 0) { + Caret caret = c.getCaret(); + int dot = caret.getDot(); + caret.setDot(dot - moveBack); + } + + return result[0]; + } + + protected void insertString(BaseDocument doc, int substitutionOffset, + String substituteText, JTextComponent c) throws BadLocationException { + doc.insertString(substitutionOffset, substituteText, null); + } + + protected void reindent(JTextComponent c) { + + } + + public static class BladeTag extends BladeCompletionItem { + + public BladeTag(String name, int substitutionOffset) { + super(name, substitutionOffset, null); + } + } + + public static class InlineDirective extends BladeCompletionItem { + + public InlineDirective(String directive, int substitutionOffset, + String description) { + super(directive, substitutionOffset, description); + } + + @Override + protected String getRightHtmlText() { + return getDescription(); + } + + @Override + protected ImageIcon getIcon() { + String path = ResourceUtilities.DIRECTIVE_ICON; + return ImageUtilities.loadImageIcon(path, false); + } + } + + public static class DirectiveWithArg extends InlineDirective { + + public DirectiveWithArg(String directive, int substitutionOffset, + String description) { + super(directive, substitutionOffset, description); + } + + @Override + protected String getSubstituteText() { + String template = getItemText() + "($$${arg})"; // NOI18N + switch (getName()) { + case BladeDirectivesUtils.DIRECTIVE_INCLUDE, + BladeDirectivesUtils.DIRECTIVE_EXTENDS -> + template = getItemText() + "('${path}')"; // NOI18N + } + return template; Review Comment: same pattern here ########## php/php.blade/src/org/netbeans/modules/php/blade/editor/completion/BladeCompletionProposal.java: ########## @@ -0,0 +1,468 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.php.blade.editor.completion; + +import java.util.Collections; +import java.util.Set; +import javax.swing.ImageIcon; +import org.netbeans.modules.csl.api.CompletionProposal; +import org.netbeans.modules.csl.api.ElementHandle; +import org.netbeans.modules.csl.api.ElementKind; +import org.netbeans.modules.csl.api.HtmlFormatter; +import org.netbeans.modules.csl.api.Modifier; +import org.netbeans.modules.php.blade.csl.elements.ClassElement; +import org.netbeans.modules.php.blade.editor.ResourceUtilities; +import org.netbeans.modules.php.blade.syntax.annotation.Directive; +import org.netbeans.modules.php.blade.syntax.annotation.Tag; + +import org.openide.filesystems.FileObject; +import org.openide.util.ImageUtilities; + +/** + * + * @author bogdan + */ +public class BladeCompletionProposal implements CompletionProposal { + + final CompletionRequest request; + protected final ElementHandle element; + final String previewValue; + protected Directive directive; + + public BladeCompletionProposal(ElementHandle element, CompletionRequest request, String previewValue) { + this.element = element; + this.request = request; + this.previewValue = previewValue; + } + + public BladeCompletionProposal(ElementHandle element, CompletionRequest request, Directive directive) { + this.element = element; + this.request = request; + this.previewValue = directive.name(); + this.directive = directive; + } + + @Override + public int getAnchorOffset() { + return request.anchorOffset; + } + + @Override + public ElementHandle getElement() { + return element; + } + + @Override + public String getName() { + return element.getName(); + } + + @Override + public String getSortText() { + return getName(); + } + + @Override + public int getSortPrioOverride() { + return 0; + } + + @Override + public String getLhsHtml(HtmlFormatter formatter) { + formatter.name(getKind(), true); + formatter.appendHtml("<font>"); + formatter.appendHtml("<b>"); + formatter.appendText(previewValue); + formatter.appendHtml("</b>"); + formatter.appendHtml("</font>"); + formatter.name(getKind(), false); + return formatter.getText(); + } + + @Override + public ImageIcon getIcon() { + return null; + } + + @Override + public Set<Modifier> getModifiers() { + return Collections.emptySet(); + } + + @Override + public String getCustomInsertTemplate() { + return null; + } + + @Override + public String getInsertPrefix() { + StringBuilder template = new StringBuilder(); + template.append(getName()); + return template.toString(); + + } + + @Override + public String getRhsHtml(HtmlFormatter formatter) { + FileObject file = null; + if (element != null) { + file = element.getFileObject(); + } + if (file != null) { + formatter.reset(); + formatter.appendText(" "); + formatter.appendText(file.getName()); + } + return formatter.getText(); + } + + @Override + public ElementKind getKind() { + return ElementKind.CONSTRUCTOR; + } + + @Override + public boolean isSmart() { + return true; + } + + public static class PhpElementItem extends BladeCompletionProposal { + + public PhpElementItem(ElementHandle element, CompletionRequest request, String previewValue) { + super(element, request, previewValue); + } + + @Override + public String getRhsHtml(HtmlFormatter formatter) { + FileObject file = null; + if (this.getElement() != null) { + file = this.getElement().getFileObject(); + } + if (file != null) { + formatter.reset(); + formatter.appendText(" "); + formatter.appendText(file.getNameExt()); + } + return formatter.getText(); + } + } + + public static class NamespaceItem extends PhpElementItem { + + public NamespaceItem(ElementHandle element, CompletionRequest request, String previewValue) { + super(element, request, previewValue); + } + + @Override + public ElementKind getKind() { + return ElementKind.PACKAGE; + } + + @Override + public int getSortPrioOverride() { + return -50;//priority + } + } + + public static class DirectiveItem extends BladeCompletionProposal { + + public DirectiveItem(ElementHandle element, CompletionRequest request, String previewValue) { + super(element, request, previewValue); + } + + } + + public static class ClassItem extends PhpElementItem { + + protected String namespace = null; + + public ClassItem(ClassElement element, CompletionRequest request, String previewValue) { + super(element, request, previewValue); + this.namespace = element.getNamespace(); + } + + @Override + public ElementKind getKind() { + return ElementKind.CLASS; + } + + @Override + public String getRhsHtml(HtmlFormatter formatter) { + if (namespace != null && namespace.length() > 0) { + return namespace; + } + return super.getRhsHtml(formatter); + } + + @Override + public int getSortPrioOverride() { + return 10;//priority + } + + @Override + public String getCustomInsertTemplate() { + if (namespace != null && namespace.length() > 0) { + return "\\" + namespace + "\\" + element.getName(); + } + return element.getName(); + } + } + + public static class FunctionItem extends PhpElementItem { + + protected final String namespace; + + public FunctionItem(ElementHandle element, CompletionRequest request, String previewValue) { + super(element, request, previewValue); + this.namespace = null; + } + + public FunctionItem(ElementHandle element, CompletionRequest request, + String namespace, + String previewValue) { + super(element, request, previewValue); + this.namespace = namespace; + } + + @Override + public ElementKind getKind() { + return ElementKind.METHOD; + } + + @Override + public int getSortPrioOverride() { + return 20;//priority + } + + @Override + public String getRhsHtml(HtmlFormatter formatter) { + if (namespace != null && namespace.length() > 0) { + return namespace; + } + return super.getRhsHtml(formatter); + } + + } + + public static class ConstantItem extends PhpElementItem { + + public ConstantItem(ElementHandle element, CompletionRequest request, String previewValue) { + super(element, request, previewValue); + } + + @Override + public ElementKind getKind() { + return ElementKind.CONSTANT; + } + + } + + public static class VariableItem extends BladeCompletionProposal { + + public VariableItem(ElementHandle element, CompletionRequest request, String previewValue) { + super(element, request, previewValue); + } + + @Override + public ElementKind getKind() { + return ElementKind.VARIABLE; + } + + } + + public static class BladeVariableItem extends BladeCompletionProposal { + + public BladeVariableItem(ElementHandle element, CompletionRequest request, String previewValue) { + super(element, request, previewValue); + } + + @Override + public ElementKind getKind() { + return ElementKind.VARIABLE; + } + + @Override + public String getRhsHtml(HtmlFormatter formatter) { + return "blade"; + } + } + + public static class CompletionRequest { + + public int anchorOffset; + public int carretOffset; + public String prefix; + } + + public static class BladeTag extends BladeCompletionProposal { + + protected Tag tag; + + public BladeTag(ElementHandle element, CompletionRequest request, Tag tag) { + super(element, request, ""); + this.tag = tag; + } + + @Override + public String getCustomInsertTemplate() { + return tag.openTag() + " ${cursor} " + tag.closeTag(); + } + + @Override + public String getLhsHtml(HtmlFormatter formatter) { + return tag.openTag() + " " + tag.closeTag(); + } + + @Override + public String getRhsHtml(HtmlFormatter formatter) { + return tag.description(); + } + + @Override + public int getSortPrioOverride() { + return 0; + } + } + + public static class DirectiveProposal extends BladeCompletionProposal { + + public DirectiveProposal(ElementHandle element, CompletionRequest request, Directive directive) { + super(element, request, directive); + } + + public DirectiveProposal(ElementHandle element, CompletionRequest request, String previewValue) { + super(element, request, previewValue); + } + + @Override + public ImageIcon getIcon() { + String path = ResourceUtilities.DIRECTIVE_ICON; + return ImageUtilities.loadImageIcon(path, false); + } + + @Override + public String getRhsHtml(HtmlFormatter formatter) { + if (this.directive == null) { + return null; + } + + if (directive.description().isEmpty() && !this.directive.since().isEmpty()) { + return "v" + this.directive.since(); + } + return this.directive.description(); + } + + } + + public static class CustomDirective extends DirectiveProposal { + + public CustomDirective(ElementHandle element, CompletionRequest request, String preview) { + super(element, request, preview); + } + + @Override + public String getRhsHtml(HtmlFormatter formatter) { + if (this.getElement().getFileObject() != null) { + return this.getElement().getFileObject().getNameExt(); + } + return "custom directive"; + } + + } + + public static class InlineDirective extends DirectiveProposal { + + public InlineDirective(ElementHandle element, CompletionRequest request, Directive directive) { + super(element, request, directive); + } + + } + + public static class DirectiveWithArg extends InlineDirective { + + public DirectiveWithArg(ElementHandle element, CompletionRequest request, Directive directive) { + super(element, request, directive); + } + + @Override + public String getCustomInsertTemplate() { + String template = getName() + "($$${arg})"; + switch (getName()) { + case "@include": + case "@extends": + template = getName() + "('${path}')"; + break; + } + return template; + } + + @Override + public String getLhsHtml(HtmlFormatter formatter) { + return getName() + "()"; + } + } + + public static class BlockDirective extends DirectiveProposal { + + public BlockDirective(ElementHandle element, CompletionRequest request, Directive directive) { + super(element, request, directive); + } + + @Override + public String getLhsHtml(HtmlFormatter formatter) { + return getName() + " ... " + directive.endtag(); + } + + @Override + public String getCustomInsertTemplate() { + return getName() + "\n ${selection} ${cursor}\n" + directive.endtag(); + } + + } + + public static class BlockDirectiveWithArg extends DirectiveProposal { + + public BlockDirectiveWithArg(ElementHandle element, CompletionRequest request, Directive directive) { + super(element, request, directive); + } + + @Override + public String getLhsHtml(HtmlFormatter formatter) { + return getName() + "() ... " + directive.endtag(); + } + + @Override + public String getCustomInsertTemplate() { + String template = getName() + "($$${arg})\n ${cursor}\n" + directive.endtag(); + + switch (getName()) { + case "@foreach": // NOI18N + template = getName() + "($$${array} as $$${item})\n ${selection}${cursor}\n" + directive.endtag(); + break; + case "@section": // NOI18N + case "@session": // NOI18N + template = getName() + "('${id}')\n ${cursor}\n" + directive.endtag(); + break; + } + + return template; Review Comment: same pattern here. The initial assignment can be moved into the default case. ########## php/php.blade/src/org/netbeans/modules/php/blade/editor/embedding/BladeHtmlEmbeddingProvider.java: ########## @@ -0,0 +1,101 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.php.blade.editor.embedding; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.netbeans.api.lexer.Token; +import org.netbeans.api.lexer.TokenHierarchy; +import org.netbeans.api.lexer.TokenId; +import org.netbeans.api.lexer.TokenSequence; +import org.netbeans.modules.parsing.api.Embedding; +import org.netbeans.modules.parsing.api.Snapshot; +import org.netbeans.modules.parsing.spi.EmbeddingProvider; +import org.netbeans.modules.php.blade.editor.BladeLanguage; +import org.netbeans.modules.php.blade.editor.lexer.BladeTokenId; + +/** + * this will enable braces matches of html elements + * + * @author bhaidu + */ [email protected]( + mimeType = BladeLanguage.MIME_TYPE, + targetMimeType = "text/html") +public class BladeHtmlEmbeddingProvider extends EmbeddingProvider { + public static final String FILLER = " "; + public static final String TARGET_MIME_TYPE = "text/html"; //NOI18N + + @Override + public List<Embedding> getEmbeddings(final Snapshot snapshot) { + TokenHierarchy<?> tokenHierarchy = snapshot.getTokenHierarchy(); + TokenSequence<?> sequence = tokenHierarchy.tokenSequence(); + + if (sequence == null || !sequence.isValid()) { + return Collections.emptyList(); + } + sequence.moveStart(); + List<Embedding> embeddings = new ArrayList<>(); + + int offset = 0; + int len = 0; + + String fake; + + try { + while (sequence.moveNext()) { + Token<?> t = sequence.token(); + offset = sequence.offset(); + TokenId id = t.id(); + len += t.length(); + String tText = t.text().toString(); + if (len == 0) { + continue; + } + if (id.equals(BladeTokenId.HTML)) { + embeddings.add(snapshot.create(offset, t.length(), TARGET_MIME_TYPE)); + } else { + fake = new String(new char[tText.length()]).replace("\0", FILLER); + embeddings.add(snapshot.create(fake, TARGET_MIME_TYPE)); + } + } + } catch (Exception ex) { + //Exceptions.printStackTrace(ex); + return Collections.emptyList(); + } + + //LOGGER.log(Level.INFO, "html ebedding finished for {0}, it took " + (System.currentTimeMillis() - startTime), snapshot.getSource().getFileObject().getName()); + + if (embeddings.isEmpty()) { + return Collections.singletonList(snapshot.create("", TARGET_MIME_TYPE)); + } else { + return Collections.singletonList(Embedding.create(embeddings)); + } Review Comment: consider using `List.of()`, `Map.of()` etc instead of `Collection.singleton*()` or `.empty*()` if the collection can't have null items. This is more optimized for situations when someone calls `copyOf()` later. ########## php/php.blade/src/org/netbeans/modules/php/blade/syntax/antlr4/v10/BladeAntlrLexer.java: ########## @@ -0,0 +1,2607 @@ +// Generated from java-escape by ANTLR 4.11.1 + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.netbeans.modules.php.blade.syntax.antlr4.v10; + +import org.antlr.v4.runtime.Lexer; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.TokenStream; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.misc.*; + +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue"}) +public class BladeAntlrLexer extends LexerAdaptor { + static { RuntimeMetaData.checkVersion("4.11.1", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + PHP_EXPRESSION=1, PHP_VARIABLE=2, PHP_KEYWORD=3, PHP_NEW=4, PHP_IDENTIFIER=5, + PHP_NAMESPACE_PATH=6, PHP_STATIC_ACCESS=7, PHP_CLASS_KEYWORD=8, PHP_INSTANCE_ACCESS=9, + BLADE_PARAM_EXTRA=10, BLADE_PARAM_LPAREN=11, BLADE_PARAM_RPAREN=12, BLADE_EXPR_LPAREN=13, + BLADE_EXPR_RPAREN=14, BL_SQ_LPAREN=15, BL_SQ_LRAREN=16, BL_PARAM_STRING=17, + BL_PARAM_ASSIGN=18, BL_COMMA=19, BL_PARAM_COMMA=20, PHP_EXPR_STRING=21, + ERROR=22, HTML=23, BLADE_COMMENT=24, D_IF=25, D_ELSEIF=26, D_ELSE=27, + D_ENDIF=28, D_SWITCH=29, D_CASE=30, D_DEFAULT=31, D_ENDSWITCH=32, D_EMPTY=33, + D_ENDEMPTY=34, D_COND_BLOCK_START=35, D_COND_BLOCK_END=36, D_FOREACH=37, + D_ENDFOREACH=38, D_FOR=39, D_ENDFOR=40, D_FORELSE=41, D_ENDFORELSE=42, + D_WHILE=43, D_ENDWHILE=44, D_BREAK=45, D_LOOP_ACTION=46, D_INCLUDE=47, + D_INCLUDE_IF=48, D_INCLUDE_WHEN=49, D_INCLUDE_FIRST=50, D_INCLUDE_UNLESS=51, + D_EACH=52, D_EXTENDS=53, D_JS=54, D_JSON=55, D_SECTION=56, D_HAS_SECTION=57, + D_SECTION_MISSING=58, D_ENDSECTION=59, D_YIELD=60, D_PARENT=61, D_SHOW=62, + D_OVERWRITE=63, D_STOP=64, D_APPEND=65, D_ONCE=66, D_ENDONCE=67, D_STACK=68, + D_PUSH=69, D_ENDPUSH=70, D_PUSH_IF=71, D_ENDPUSH_IF=72, D_PUSH_ONCE=73, + D_ENDPUSH_ONCE=74, D_PREPEND=75, D_ENDPREPEND=76, D_PROPS=77, D_FRAGMENT=78, + D_ENDFRAGMENT=79, D_CSRF=80, D_METHOD=81, D_ERROR=82, D_ENDERROR=83, D_PRODUCTION=84, + D_ENDPRODUCTION=85, D_ENV=86, D_ENDENV=87, D_AUTH_START=88, D_AUTH_END=89, + D_PERMISSION_START=90, D_PERMISSION_ELSE=91, D_PERMISSION_END=92, D_CLASS=93, + D_STYLE=94, D_HTML_ATTR_EXPR=95, D_AWARE=96, D_SESSION=97, D_ENDSESSION=98, + D_DD=99, D_LANG=100, D_USE=101, D_INJECT=102, D_PHP=103, D_VERBATIM=104, + D_ENDVERBATIM=105, D_LIVEWIRE=106, D_ASSET_BUNDLER=107, D_MISC=108, D_CUSTOM=109, + D_UNKNOWN_ATTR_ENC=110, D_UNKNOWN=111, CONTENT_TAG_OPEN=112, RAW_TAG_OPEN=113, + PHP_INLINE_START=114, HTML_COMPONENT_PREFIX=115, JS_SCRIPT=116, HTML_TAG_START=117, + HTML_CLOSE_TAG=118, STRING_PATH=119, HTML_PATH=120, HTML_TEXT=121, HTML_IDENTIFIER=122, + EQ=123, WS=124, OTHER=125, BLADE_COMMENT_START=126, CONTENT_TAG_CLOSE=127, + REGULAR_ECHO_EXPR_MORE=128, RAW_TAG_CLOSE=129, RAW_ECHO_EXPR_MORE=130, + WS_EXPR_ESCAPE=131, WS_EXPR=132, WS_COMPOSED_EXPR=133, EXPR_STRING=134, + COMPOSED_EXPR_RPAREN=135, PHP_COMPOSED_EXPRESSION=136, WS_BL_PARAM=137, + FOREACH_WS_EXPR=138, FOREACH_LOOP_LPAREN=139, FOREACH_LOOP_RPAREN=140, + FOREACH_AS=141, FOREACH_PARAM_ASSIGN=142, BL_PARAM_LINE_COMMENT=143, BL_SQ_RPAREN=144, + BL_PARAM_RPAREN=145, BL_PARAM_CONCAT_OPERATOR=146, BL_COMMA_EL=147, BL_PARAM_WS=148, + BL_NAME_STRING=149, PHP_D_BLADE_COMMENT=150, PHP_D_BLADE_ML_COMMENT=151, + D_ENDPHP=152, PHP_D_WS=153, PHP_D_PHP_COMPOSED_EXPRESSION=154, PHP_EXIT=155, + PHP_INLINE_COMMENT=156, PHP_INLINE_ML_COMMENT=157, VERBATIM_HTML=158, + BLADE_COMMENT_END=159, BLADE_COMMENT_PEEK=160, BLADE_COMMENT_MORE=161, + BLADE_COMMENT_EOF=162, AT=163, RAW_TAG_START=164, REGULAR_ECHO_STATIC_ACCESS=165, + REGULAR_ECHO_LPAREN=166, REGULAR_ECHO_RPAREN=167, REGULAR_ECHO_INSTANCE_ACCESS=168, + PHP_D_EXPR_CURLY_LPAREN=169, PHP_D_EXPR_CURLY_RPAREN=170, PHP_D_CLASS=171; + public static final int + COMMENT=2, PHP_CODE=3; + public static final int + INSIDE_REGULAR_ECHO=1, INSIDE_RAW_ECHO=2, LOOK_FOR_PHP_EXPRESSION=3, INSIDE_PHP_EXPRESSION=4, + LOOK_FOR_PHP_COMPOSED_EXPRESSION=5, INSIDE_PHP_COMPOSED_EXPRESSION=6, + LOOK_FOR_BLADE_PARAMETERS=7, FOREACH_LOOP_EXPRESSION=8, INSIDE_BLADE_PARAMETERS=9, + BLADE_INLINE_PHP=10, INSIDE_PHP_INLINE=11, VERBATIM_MODE=12, INSIDE_BLADE_COMMENT=13; + public static String[] channelNames = { + "DEFAULT_TOKEN_CHANNEL", "HIDDEN", "COMMENT", "PHP_CODE" + }; + + public static String[] modeNames = { + "DEFAULT_MODE", "INSIDE_REGULAR_ECHO", "INSIDE_RAW_ECHO", "LOOK_FOR_PHP_EXPRESSION", + "INSIDE_PHP_EXPRESSION", "LOOK_FOR_PHP_COMPOSED_EXPRESSION", "INSIDE_PHP_COMPOSED_EXPRESSION", + "LOOK_FOR_BLADE_PARAMETERS", "FOREACH_LOOP_EXPRESSION", "INSIDE_BLADE_PARAMETERS", + "BLADE_INLINE_PHP", "INSIDE_PHP_INLINE", "VERBATIM_MODE", "INSIDE_BLADE_COMMENT" + }; + + private static String[] makeRuleNames() { + return new String[] { + "CompomentIdentifier", "CssSelector", "JsFunctionStart", "StringParam", + "CssAttrSelector", "StringAttrValue", "D_IF", "D_ELSEIF", "D_ELSE", "D_ENDIF", + "D_SWITCH", "D_CASE", "D_DEFAULT", "D_ENDSWITCH", "D_EMPTY", "D_ENDEMPTY", + "D_COND_BLOCK_START", "D_COND_BLOCK_END", "D_FOREACH", "D_ENDFOREACH", + "D_FOR", "D_ENDFOR", "D_FORELSE", "D_ENDFORELSE", "D_WHILE", "D_ENDWHILE", + "D_BREAK", "D_LOOP_ACTION", "D_INCLUDE", "D_INCLUDE_IF", "D_INCLUDE_WHEN", + "D_INCLUDE_FIRST", "D_INCLUDE_UNLESS", "D_EACH", "D_EXTENDS", "D_JS", + "D_JSON", "D_SECTION", "D_HAS_SECTION", "D_SECTION_MISSING", "D_ENDSECTION", + "D_YIELD", "D_PARENT", "D_SHOW", "D_OVERWRITE", "D_STOP", "D_APPEND", + "D_ONCE", "D_ENDONCE", "D_STACK", "D_PUSH", "D_ENDPUSH", "D_PUSH_IF", + "D_ENDPUSH_IF", "D_PUSH_ONCE", "D_ENDPUSH_ONCE", "D_PREPEND", "D_ENDPREPEND", + "D_PROPS", "D_FRAGMENT", "D_ENDFRAGMENT", "D_CSRF", "D_METHOD", "D_ERROR", + "D_ENDERROR", "D_PRODUCTION", "D_ENDPRODUCTION", "D_ENV", "D_ENDENV", + "D_AUTH_START", "D_AUTH_END", "D_PERMISSION_START", "D_PERMISSION_ELSE", + "D_PERMISSION_END", "D_CLASS", "D_STYLE", "D_HTML_ATTR_EXPR", "D_AWARE", + "D_SESSION", "D_ENDSESSION", "D_DD", "D_LANG", "D_USE", "D_INJECT", "D_PHP_SHORT", + "D_PHP", "D_VERBATIM", "D_ENDVERBATIM", "D_LIVEWIRE", "D_ASSET_BUNDLER", + "D_MISC", "D_CUSTOM", "D_UNKNOWN_ATTR_ENC", "D_UNKNOWN", "CONTENT_TAG_OPEN", + "RAW_TAG_OPEN", "AT", "RAW_TAG_START", "PHP_INLINE_START", "HTML_COMPONENT_PREFIX", + "HTML_L_COMPONENT", "JS_SCRIPT", "HTML_TAG_START", "HTML_CLOSE_TAG", + "HTML_TAG_SELF_CLOSE", "HTML_CLOSE_SYMBOL", "STRING_PATH", "HTML_PATH", + "HTML_TEXT", "HTML_IDENTIFIER", "EQ", "WS", "OTHER", "NameString", "BladeLabel", + "FullIdentifier", "ESC_DOUBLE_QUOTED_STRING", "DOUBLE_QUOTED_STRING_FRAGMENT", + "SINGLE_QUOTED_STRING_FRAGMENT", "LineComment", "PhpVariable", "PhpKeyword", + "Digit", "BLADE_COMMENT_START", "EMAIL_SUBSTRING", "VERSION_WITH_AT", + "D_ESCAPES", "REGULAR_ECHO_PHP_VAR", "REGULAR_ECHO_KEYWORD", "REGULAR_PHP_NAMESPACE_PATH", + "REGULAR_ECHO_PHP_IDENTIFIER", "REGULAR_ECHO_STATIC_ACCESS", "CONTENT_TAG_CLOSE", + "REGULAR_ECHO_LPAREN", "REGULAR_ECHO_RPAREN", "REGULAR_ECHO_INSTANCE_ACCESS", + "REGULAR_ECHO_EXPR_MORE", "EXIT_REGULAR_ECHO_EOF", "RAW_ECHO_PHP_VAR", + "RAW_ECHO_KEYWORD", "RAW_ECHO_PHP_NAMESPACE_PATH", "RAW_ECHO_PHP_IDENTIFIER", + "RAW_ECHO_STATIC_ACCESS", "RAW_TAG_CLOSE", "RAW_ECHO_LPAREN", "RAW_ECHO_RPAREN", + "RAW_ECHO_INSTANCE_ACCESS", "RAW_ECHO_EXPR_MORE", "EXIT_RAW_ECHO_EOF", + "WS_EXPR_ESCAPE", "WS_EXPR", "OPEN_EXPR_PAREN_MORE", "L_OHTER_ESCAPE", + "L_OTHER", "OPEN_EXPR_PAREN", "CLOSE_EXPR_PAREN", "LPAREN", "RPAREN", + "EXIT_RPAREN", "PHP_EXPRESSION_MORE", "EXIT_EOF", "WS_COMPOSED_EXPR", + "BLADE_EXPR_LPAREN", "L_COMPOSED_EXPR_OTHER", "EXPR_SQ_LPAREN", "EXPR_SQ_RPAREN", + "EXPR_CURLY_LPAREN", "EXPR_CURLY_RPAREN", "EXPR_STRING", "COMPOSED_EXPR_PHP_VAR", + "COMPOSED_PHP_KEYWORD", "COMPOSED_PHP_NAMESPACE_PATH", "COMPOSED_EXPR_PHP_IDENTIFIER", + "COMPOSED_EXPR_STATIC_ACCESS", "COMPOSED_EXPR_LPAREN", "COMPOSED_EXPR_RPAREN", + "PHP_COMPOSED_EXPRESSION", "EXIT_COMPOSED_EXPRESSION_EOF", "WS_BL_PARAM", + "OPEN_BL_PARAM_PAREN_MORE", "L_BL_PARAM_OTHER", "FOREACH_WS_EXPR", "FOREACH_LOOP_LPAREN", + "FOREACH_LOOP_RPAREN", "FOREACH_AS", "FOREACH_PHP_VARIABLE", "FOREACH_PARAM_ASSIGN", + "LOOP_COMPOSED_PHP_KEYWORD", "LOOP_NAME_STRING", "LOOP_STATIC_ACCESS", + "LOOP_PHP_EXPRESSION", "FOREACH_EOF", "BL_PARAM_LINE_COMMENT", "BL_SQ_LPAREN", + "BL_SQ_RPAREN", "BL_CURLY_LPAREN", "BL_CURLY_RPAREN", "BL_PARAM_LPAREN", + "BL_PARAM_RPAREN", "BL_PARAM_STRING", "BL_PARAM_PHP_VARIABLE", "BL_PARAM_ASSIGN", + "BL_PARAM_PHP_KEYWORD", "BL_PARAM_CONCAT_OPERATOR", "BL_COMMA_EL", "BL_PARAM_WS", + "BL_NAME_STRING", "BL_PARAM_MORE", "BL_PARAM_EXIT_EOF", "PHP_D_BLADE_COMMENT", + "PHP_D_BLADE_ML_COMMENT", "D_ENDPHP", "PHP_D_UNKNOWN", "PHP_D_EXPR_SQ_LPAREN", + "PHP_D_EXPR_SQ_RPAREN", "PHP_D_EXPR_CURLY_LPAREN", "PHP_D_EXPR_CURLY_RPAREN", + "PHP_D_EXPR_STRING", "PHP_D_COMPOSED_EXPR_PHP_VAR", "PHP_D_NEW", "PHP_D_CLASS", + "PHP_D_COMPOSED_PHP_KEYWORD", "PHP_D_NAMESPACE_PATH", "PHP_D_COMPOSED_EXPR_PHP_CLASS_IDENTIFIER", + "PHP_D_COMPOSED_EXPR_PHP_IDENTIFIER", "PHP_D_COMPOSED_EXPR_STATIC_ACCESS", + "PHP_D_COMPOSED_EXPR_LPAREN", "PHP_D_COMPOSED_EXPR_RPAREN", "PHP_D_WS", + "PHP_D_EXIT_COMPOSED_EXPRESSION_EOF", "PHP_D_PHP_COMPOSED_EXPRESSION", + "PHP_EXIT", "PHP_INLINE_COMMENT", "PHP_INLINE_ML_COMMENT", "PHP_EXPR_SQ_LPAREN", + "PHP_EXPR_SQ_RPAREN", "PHP_EXPR_CURLY_LPAREN", "PHP_EXPR_CURLY_RPAREN", + "PHP_EXPR_STRING", "PHP_COMPOSED_EXPR_PHP_VAR", "PHP_COMPOSED_PHP_KEYWORD", + "PHP_COMPOSED_EXPR_PHP_IDENTIFIER", "PHP_COMPOSED_EXPR_STATIC_ACCESS", + "PHP_COMPOSED_EXPR_INSTANCE_ACCESS", "PHP_COMPOSED_EXPR_LPAREN", "PHP_COMPOSED_EXPR_RPAREN", + "PHP_EXIT_COMPOSED_EXPRESSION_EOF", "PHP_PHP_COMPOSED_EXPRESSION", "D_ENDVERBATIM_IN_MODE", + "VERBATIM_HTML", "EXIT_VERBATIM_MOD_EOF", "VERBATIM_HTML_MORE", "BLADE_COMMENT_END", + "BLADE_COMMENT_PEEK", "BLADE_COMMENT_MORE", "BLADE_COMMENT_EOF" + }; + } + public static final String[] ruleNames = makeRuleNames(); + + private static String[] makeLiteralNames() { + return new String[] { + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, + null, "'@if'", "'@elseif'", "'@else'", "'@endif'", "'@switch'", "'@case'", + "'@default'", "'@endswitch'", "'@empty'", "'@endempty'", null, null, + "'@foreach'", "'@endforeach'", "'@for'", "'@endfor'", "'@forelse'", "'@endforelse'", + "'@while'", "'@endwhile'", "'@break'", null, "'@include'", "'@includeIf'", + "'@includeWhen'", "'@includeFirst'", "'@includeUnless'", "'@each'", "'@extends'", + "'@js'", "'@json'", "'@section'", "'@hasSection'", "'@sectionMissing'", + "'@endsection'", "'@yield'", "'@parent'", "'@show'", "'@overwrite'", + "'@stop'", "'@append'", "'@once'", "'@endonce'", "'@stack'", "'@push'", + "'@endpush'", "'@pushIf'", "'@endPushIf'", "'@pushOnce'", "'@endPushOnce'", + "'@prepend'", "'@endprepend'", "'@props'", "'@fragment'", "'@endfragment'", + "'@csrf'", "'@method'", "'@error'", "'@enderror'", "'@production'", "'@endproduction'", + "'@env'", "'@endenv'", null, null, null, null, null, "'@class'", "'@style'", + null, "'@aware'", "'@session'", "'@endsession'", null, "'@lang'", "'@use'", + "'@inject'", null, "'@verbatim'", "'@endverbatim'", null, "'@vite'", + "'@viteReactRefresh'", null, null, null, "'{{'", "'{!!'", null, null, + null, null, null, null, null, null, null, "'='", null, null, "'{{--'", + null, null, null, null, null, null, null, null, null, null, null, null, + null, null, "'as'", null, null, null, null, "'.'", "','", null, null, + null, null, "'@endphp'", "' '", null, "'?>'", null, null, null, "'--}}'", + null, null, null, null, "'{!'", null, null, null, null, null, null, "'class'" + }; + } + private static final String[] _LITERAL_NAMES = makeLiteralNames(); + private static String[] makeSymbolicNames() { + return new String[] { + null, "PHP_EXPRESSION", "PHP_VARIABLE", "PHP_KEYWORD", "PHP_NEW", "PHP_IDENTIFIER", + "PHP_NAMESPACE_PATH", "PHP_STATIC_ACCESS", "PHP_CLASS_KEYWORD", "PHP_INSTANCE_ACCESS", + "BLADE_PARAM_EXTRA", "BLADE_PARAM_LPAREN", "BLADE_PARAM_RPAREN", "BLADE_EXPR_LPAREN", + "BLADE_EXPR_RPAREN", "BL_SQ_LPAREN", "BL_SQ_LRAREN", "BL_PARAM_STRING", + "BL_PARAM_ASSIGN", "BL_COMMA", "BL_PARAM_COMMA", "PHP_EXPR_STRING", "ERROR", + "HTML", "BLADE_COMMENT", "D_IF", "D_ELSEIF", "D_ELSE", "D_ENDIF", "D_SWITCH", + "D_CASE", "D_DEFAULT", "D_ENDSWITCH", "D_EMPTY", "D_ENDEMPTY", "D_COND_BLOCK_START", + "D_COND_BLOCK_END", "D_FOREACH", "D_ENDFOREACH", "D_FOR", "D_ENDFOR", + "D_FORELSE", "D_ENDFORELSE", "D_WHILE", "D_ENDWHILE", "D_BREAK", "D_LOOP_ACTION", + "D_INCLUDE", "D_INCLUDE_IF", "D_INCLUDE_WHEN", "D_INCLUDE_FIRST", "D_INCLUDE_UNLESS", + "D_EACH", "D_EXTENDS", "D_JS", "D_JSON", "D_SECTION", "D_HAS_SECTION", + "D_SECTION_MISSING", "D_ENDSECTION", "D_YIELD", "D_PARENT", "D_SHOW", + "D_OVERWRITE", "D_STOP", "D_APPEND", "D_ONCE", "D_ENDONCE", "D_STACK", + "D_PUSH", "D_ENDPUSH", "D_PUSH_IF", "D_ENDPUSH_IF", "D_PUSH_ONCE", "D_ENDPUSH_ONCE", + "D_PREPEND", "D_ENDPREPEND", "D_PROPS", "D_FRAGMENT", "D_ENDFRAGMENT", + "D_CSRF", "D_METHOD", "D_ERROR", "D_ENDERROR", "D_PRODUCTION", "D_ENDPRODUCTION", + "D_ENV", "D_ENDENV", "D_AUTH_START", "D_AUTH_END", "D_PERMISSION_START", + "D_PERMISSION_ELSE", "D_PERMISSION_END", "D_CLASS", "D_STYLE", "D_HTML_ATTR_EXPR", + "D_AWARE", "D_SESSION", "D_ENDSESSION", "D_DD", "D_LANG", "D_USE", "D_INJECT", + "D_PHP", "D_VERBATIM", "D_ENDVERBATIM", "D_LIVEWIRE", "D_ASSET_BUNDLER", + "D_MISC", "D_CUSTOM", "D_UNKNOWN_ATTR_ENC", "D_UNKNOWN", "CONTENT_TAG_OPEN", + "RAW_TAG_OPEN", "PHP_INLINE_START", "HTML_COMPONENT_PREFIX", "JS_SCRIPT", + "HTML_TAG_START", "HTML_CLOSE_TAG", "STRING_PATH", "HTML_PATH", "HTML_TEXT", + "HTML_IDENTIFIER", "EQ", "WS", "OTHER", "BLADE_COMMENT_START", "CONTENT_TAG_CLOSE", + "REGULAR_ECHO_EXPR_MORE", "RAW_TAG_CLOSE", "RAW_ECHO_EXPR_MORE", "WS_EXPR_ESCAPE", + "WS_EXPR", "WS_COMPOSED_EXPR", "EXPR_STRING", "COMPOSED_EXPR_RPAREN", + "PHP_COMPOSED_EXPRESSION", "WS_BL_PARAM", "FOREACH_WS_EXPR", "FOREACH_LOOP_LPAREN", + "FOREACH_LOOP_RPAREN", "FOREACH_AS", "FOREACH_PARAM_ASSIGN", "BL_PARAM_LINE_COMMENT", + "BL_SQ_RPAREN", "BL_PARAM_RPAREN", "BL_PARAM_CONCAT_OPERATOR", "BL_COMMA_EL", + "BL_PARAM_WS", "BL_NAME_STRING", "PHP_D_BLADE_COMMENT", "PHP_D_BLADE_ML_COMMENT", + "D_ENDPHP", "PHP_D_WS", "PHP_D_PHP_COMPOSED_EXPRESSION", "PHP_EXIT", + "PHP_INLINE_COMMENT", "PHP_INLINE_ML_COMMENT", "VERBATIM_HTML", "BLADE_COMMENT_END", + "BLADE_COMMENT_PEEK", "BLADE_COMMENT_MORE", "BLADE_COMMENT_EOF", "AT", + "RAW_TAG_START", "REGULAR_ECHO_STATIC_ACCESS", "REGULAR_ECHO_LPAREN", + "REGULAR_ECHO_RPAREN", "REGULAR_ECHO_INSTANCE_ACCESS", "PHP_D_EXPR_CURLY_LPAREN", + "PHP_D_EXPR_CURLY_RPAREN", "PHP_D_CLASS" + }; + } + private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = "<INVALID>"; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + + public BladeAntlrLexer(CharStream input) { + super(input); + _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + + @Override + public String getGrammarFileName() { return "BladeAntlrLexer.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public String[] getChannelNames() { return channelNames; } + + @Override + public String[] getModeNames() { return modeNames; } + + @Override + public ATN getATN() { return _ATN; } + + @Override + public void action(RuleContext _localctx, int ruleIndex, int actionIndex) { + switch (ruleIndex) { + case 99: + HTML_COMPONENT_PREFIX_action((RuleContext)_localctx, actionIndex); + break; + case 104: + HTML_TAG_SELF_CLOSE_action((RuleContext)_localctx, actionIndex); + break; + case 105: + HTML_CLOSE_SYMBOL_action((RuleContext)_localctx, actionIndex); + break; + case 109: + HTML_IDENTIFIER_action((RuleContext)_localctx, actionIndex); + break; + case 154: + OPEN_EXPR_PAREN_action((RuleContext)_localctx, actionIndex); + break; + case 155: + CLOSE_EXPR_PAREN_action((RuleContext)_localctx, actionIndex); + break; + case 156: + LPAREN_action((RuleContext)_localctx, actionIndex); + break; + case 157: + RPAREN_action((RuleContext)_localctx, actionIndex); + break; + case 162: + BLADE_EXPR_LPAREN_action((RuleContext)_localctx, actionIndex); + break; + case 164: + EXPR_SQ_LPAREN_action((RuleContext)_localctx, actionIndex); + break; + case 165: + EXPR_SQ_RPAREN_action((RuleContext)_localctx, actionIndex); + break; + case 166: + EXPR_CURLY_LPAREN_action((RuleContext)_localctx, actionIndex); + break; + case 167: + EXPR_CURLY_RPAREN_action((RuleContext)_localctx, actionIndex); + break; + case 174: + COMPOSED_EXPR_LPAREN_action((RuleContext)_localctx, actionIndex); + break; + case 175: + COMPOSED_EXPR_RPAREN_action((RuleContext)_localctx, actionIndex); + break; + case 179: + OPEN_BL_PARAM_PAREN_MORE_action((RuleContext)_localctx, actionIndex); + break; + case 182: + FOREACH_LOOP_LPAREN_action((RuleContext)_localctx, actionIndex); + break; + case 183: + FOREACH_LOOP_RPAREN_action((RuleContext)_localctx, actionIndex); + break; + case 193: + BL_SQ_LPAREN_action((RuleContext)_localctx, actionIndex); + break; + case 194: + BL_SQ_RPAREN_action((RuleContext)_localctx, actionIndex); + break; + case 195: + BL_CURLY_LPAREN_action((RuleContext)_localctx, actionIndex); + break; + case 196: + BL_CURLY_RPAREN_action((RuleContext)_localctx, actionIndex); + break; + case 197: + BL_PARAM_LPAREN_action((RuleContext)_localctx, actionIndex); + break; + case 198: + BL_PARAM_RPAREN_action((RuleContext)_localctx, actionIndex); + break; + case 204: + BL_COMMA_EL_action((RuleContext)_localctx, actionIndex); + break; + } + } + private void HTML_COMPONENT_PREFIX_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 0: + this.compomentTagOpen = true; + break; + } + } + private void HTML_TAG_SELF_CLOSE_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 1: + this.compomentTagOpen = false; + break; + } + } + private void HTML_CLOSE_SYMBOL_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 2: + this.compomentTagOpen = false; + break; + } + } + private void HTML_IDENTIFIER_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 3: + this.consumeHtmlIdentifier(); + break; + } + } + private void OPEN_EXPR_PAREN_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 4: + this.increaseRoundParenBalance(); + break; + } + } + private void CLOSE_EXPR_PAREN_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 5: + this.decreaseRoundParenBalance(); + break; + } + } + private void LPAREN_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 6: + this.increaseRoundParenBalance(); + break; + } + } + private void RPAREN_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 7: + this.decreaseRoundParenBalance(); + break; + } + } + private void BLADE_EXPR_LPAREN_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 8: + this.roundParenBalance = 0; + break; + } + } + private void EXPR_SQ_LPAREN_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 9: + this.squareParenBalance++; + break; + } + } + private void EXPR_SQ_RPAREN_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 10: + this.squareParenBalance--; + break; + } + } + private void EXPR_CURLY_LPAREN_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 11: + this.curlyParenBalance++; + break; + } + } + private void EXPR_CURLY_RPAREN_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 12: + this.curlyParenBalance--; + break; + } + } + private void COMPOSED_EXPR_LPAREN_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 13: + this.increaseRoundParenBalance(); + break; + } + } + private void COMPOSED_EXPR_RPAREN_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 14: + consumeExprRParen(); + break; + } + } + private void OPEN_BL_PARAM_PAREN_MORE_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 15: + this.roundParenBalance = 0; + break; + } + } + private void FOREACH_LOOP_LPAREN_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 16: + this.increaseRoundParenBalance(); + break; + } + } + private void FOREACH_LOOP_RPAREN_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 17: + this.decreaseRoundParenBalance(); if (this.roundParenBalance == 0){this.popMode();} + break; + } + } + private void BL_SQ_LPAREN_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 18: + this.squareParenBalance++; + break; + } + } + private void BL_SQ_RPAREN_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 19: + this.squareParenBalance--; + break; + } + } + private void BL_CURLY_LPAREN_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 20: + this.curlyParenBalance++; + break; + } + } + private void BL_CURLY_RPAREN_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 21: + this.curlyParenBalance--; + break; + } + } + private void BL_PARAM_LPAREN_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 22: + this.increaseRoundParenBalance(); + break; + } + } + private void BL_PARAM_RPAREN_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 23: + consumeParamRParen(); + break; + } + } + private void BL_COMMA_EL_action(RuleContext _localctx, int actionIndex) { + switch (actionIndex) { + case 24: + this.consumeBladeParamComma(); + break; + } + } + @Override + public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) { + switch (ruleIndex) { + case 2: + return JsFunctionStart_sempred((RuleContext)_localctx, predIndex); + case 84: + return D_PHP_SHORT_sempred((RuleContext)_localctx, predIndex); + case 85: + return D_PHP_sempred((RuleContext)_localctx, predIndex); + case 91: + return D_CUSTOM_sempred((RuleContext)_localctx, predIndex); + case 92: + return D_UNKNOWN_ATTR_ENC_sempred((RuleContext)_localctx, predIndex); + case 93: + return D_UNKNOWN_sempred((RuleContext)_localctx, predIndex); + case 100: + return HTML_L_COMPONENT_sempred((RuleContext)_localctx, predIndex); + case 149: + return WS_EXPR_ESCAPE_sempred((RuleContext)_localctx, predIndex); + case 152: + return L_OHTER_ESCAPE_sempred((RuleContext)_localctx, predIndex); + case 154: + return OPEN_EXPR_PAREN_sempred((RuleContext)_localctx, predIndex); + case 155: + return CLOSE_EXPR_PAREN_sempred((RuleContext)_localctx, predIndex); + case 156: + return LPAREN_sempred((RuleContext)_localctx, predIndex); + case 157: + return RPAREN_sempred((RuleContext)_localctx, predIndex); + case 158: + return EXIT_RPAREN_sempred((RuleContext)_localctx, predIndex); + case 219: + return PHP_D_NEW_sempred((RuleContext)_localctx, predIndex); + case 249: + return VERBATIM_HTML_sempred((RuleContext)_localctx, predIndex); + case 253: + return BLADE_COMMENT_PEEK_sempred((RuleContext)_localctx, predIndex); + } + return true; + } + private boolean JsFunctionStart_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 0: + return this._input.LA(1) != '{'; + } + return true; + } + private boolean D_PHP_SHORT_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 1: + return this._input.LA(1) == '('; + } + return true; + } + private boolean D_PHP_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 2: + return this._input.LA(1) == ' ' || this._input.LA(1) == '\r' || this._input.LA(1) == '\n'; + } + return true; + } + private boolean D_CUSTOM_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 3: + return this._input.LA(1) == '(' || + (this._input.LA(1) == ' ' && this._input.LA(2) == '('); + } + return true; + } + private boolean D_UNKNOWN_ATTR_ENC_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 4: + return this._input.LA(1) == '"'; + } + return true; + } + private boolean D_UNKNOWN_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 5: + return this._input.LA(1) != '"'; + } + return true; + } + private boolean HTML_L_COMPONENT_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 6: + return this._input.LA(1) == '>'; + } + return true; + } + private boolean WS_EXPR_ESCAPE_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 7: + return this._input.LA(1) == '@'; + } + return true; + } + private boolean L_OHTER_ESCAPE_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 8: + return this._input.LA(1) == '@'; + } + return true; + } + private boolean OPEN_EXPR_PAREN_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 9: + return this.roundParenBalance == 0; + } + return true; + } + private boolean CLOSE_EXPR_PAREN_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 10: + return this.roundParenBalance == 1; + } + return true; + } + private boolean LPAREN_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 11: + return this.roundParenBalance > 0; + } + return true; + } + private boolean RPAREN_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 12: + return this.roundParenBalance > 0; + } + return true; + } + private boolean EXIT_RPAREN_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 13: + return this.roundParenBalance == 0; + } + return true; + } + private boolean PHP_D_NEW_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 14: + return this._input.LA(1) == ' '; + } + return true; + } + private boolean VERBATIM_HTML_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 15: + return + this._input.LA(1) == '@' && + this._input.LA(2) == 'e' && + this._input.LA(3) == 'n' && + this._input.LA(4) == 'd' && + this._input.LA(5) == 'v' && + this._input.LA(6) == 'e' && + this._input.LA(7) == 'r' + ; + } + return true; + } + private boolean BLADE_COMMENT_PEEK_sempred(RuleContext _localctx, int predIndex) { + switch (predIndex) { + case 16: + return + this._input.LA(1) == '-' && + this._input.LA(2) == '-' && + this._input.LA(3) == '}' && + this._input.LA(4) == '}' + ; + } + return true; + } + + private static final String _serializedATNSegment0 = + "\u0004\u0000\u00ab\u0b4c\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff"+ + "\uffff\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff"+ + "\uffff\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff"+ + "\uffff\u0006\uffff\uffff\u0006\uffff\uffff\u0006\uffff\uffff\u0002\u0000"+ + "\u0007\u0000\u0002\u0001\u0007\u0001\u0002\u0002\u0007\u0002\u0002\u0003"+ + "\u0007\u0003\u0002\u0004\u0007\u0004\u0002\u0005\u0007\u0005\u0002\u0006"+ Review Comment: regarding generated code. I believe we ended up agreeing to try to generate antlr outputs during build but don't commit it to the repo. The reason is because generated antlr code is not very "stable", it produces huge diffs when the version updates and those aren't reviewable anyway. (e.g the marked section) The second reason would be antlr updates, this makes sure the code fits to the version if someone happens to update the antlr lib at some point. example: https://github.com/apache/netbeans/pull/7189, https://github.com/apache/netbeans/pull/7186 etc cc @neilcsmith-net @lkishalmi -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected] For further information about the NetBeans mailing lists, visit: https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists
