This is an automated email from the ASF dual-hosted git repository. junichi11 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/netbeans.git
The following commit(s) were added to refs/heads/master by this push: new fb0636966f Fix #5578 namespaces/use placement in FixUsesPerformer new d4944b7d76 Merge pull request #5579 from rossluk/php/fix-uses-performer-fix fb0636966f is described below commit fb0636966fd4ea4a545c829d3f58cabc8d07b43c Author: Andrei Rosliuk <arosl...@gmail.com> AuthorDate: Tue Feb 28 13:21:01 2023 +0100 Fix #5578 namespaces/use placement in FixUsesPerformer --- .../php/editor/actions/FixUsesPerformer.java | 221 ++++++++++++--------- .../data/testfiles/actions/testGH5578/01/B.php | 23 +++ .../actions/testGH5578/01/testGH5578_01.php | 36 ++++ .../testGH5578/01/testGH5578_01.php.fixUses | 38 ++++ .../data/testfiles/actions/testGH5578/02/B.php | 23 +++ .../actions/testGH5578/02/testGH5578_02.php | 35 ++++ .../testGH5578/02/testGH5578_02.php.fixUses | 37 ++++ .../actions/testGH5578/03/testGH5578_03.php | 42 ++++ .../testGH5578/03/testGH5578_03.php.fixUses | 46 +++++ .../actions/testGH5578/04/testGH5578_04.php | 43 ++++ .../testGH5578/04/testGH5578_04.php.fixUses | 46 +++++ .../actions/testGH5578/05/testGH5578_05.php | 44 ++++ .../testGH5578/05/testGH5578_05.php.fixUses | 46 +++++ .../actions/testGH5578/06/testGH5578_06.php | 49 +++++ .../testGH5578/06/testGH5578_06.php.fixUses | 51 +++++ .../actions/testGH5578/07/testGH5578_07.php | 49 +++++ .../testGH5578/07/testGH5578_07.php.fixUses | 51 +++++ .../data/testfiles/actions/testGH5578/08/B.php | 23 +++ .../actions/testGH5578/08/testGH5578_08.php | 41 ++++ .../testGH5578/08/testGH5578_08.php.fixUses | 43 ++++ .../php/editor/actions/FixUsesPerformerTest.java | 50 +++++ 21 files changed, 941 insertions(+), 96 deletions(-) diff --git a/php/php.editor/src/org/netbeans/modules/php/editor/actions/FixUsesPerformer.java b/php/php.editor/src/org/netbeans/modules/php/editor/actions/FixUsesPerformer.java index 809ccbd85a..b0190da508 100644 --- a/php/php.editor/src/org/netbeans/modules/php/editor/actions/FixUsesPerformer.java +++ b/php/php.editor/src/org/netbeans/modules/php/editor/actions/FixUsesPerformer.java @@ -19,6 +19,7 @@ package org.netbeans.modules.php.editor.actions; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Iterator; @@ -28,7 +29,6 @@ import java.util.Objects; import java.util.stream.Collectors; import javax.swing.text.BadLocationException; import javax.swing.text.Document; -import org.netbeans.api.annotations.common.CheckForNull; import org.netbeans.api.editor.document.LineDocumentUtils; import org.netbeans.api.lexer.TokenSequence; import org.netbeans.editor.BaseDocument; @@ -46,10 +46,8 @@ import org.netbeans.modules.php.editor.indent.CodeStyle; import org.netbeans.modules.php.editor.lexer.LexUtilities; import org.netbeans.modules.php.editor.lexer.PHPTokenId; import org.netbeans.modules.php.editor.model.GroupUseScope; -import org.netbeans.modules.php.editor.model.ModelElement; import org.netbeans.modules.php.editor.model.ModelUtils; import org.netbeans.modules.php.editor.model.NamespaceScope; -import org.netbeans.modules.php.editor.model.Scope; import org.netbeans.modules.php.editor.model.UseScope; import org.netbeans.modules.php.editor.parser.PHPParseResult; import org.netbeans.modules.php.editor.parser.UnusedUsesCollector; @@ -89,6 +87,7 @@ public class FixUsesPerformer { private final Options options; private EditList editList; private BaseDocument baseDocument; + private NamespaceScope namespaceScope; public FixUsesPerformer( final PHPParseResult parserResult, @@ -108,18 +107,16 @@ public class FixUsesPerformer { if (document instanceof BaseDocument) { baseDocument = (BaseDocument) document; editList = new EditList(baseDocument); - processExistingUses(); - processSelections(); + namespaceScope = ModelUtils.getNamespaceScope(parserResult, importData.caretPosition); + assert namespaceScope != null; + processSelections(processExistingUses(importData.caretPosition)); editList.apply(); } } @NbBundle.Messages("FixUsesPerformer.noChanges=Fix imports: No Changes") - private void processSelections() { + private void processSelections(int startOffset) { final List<ImportData.DataItem> dataItems = resolveDuplicateSelections(); - NamespaceScope namespaceScope = ModelUtils.getNamespaceScope(parserResult, importData.caretPosition); - assert namespaceScope != null; - int startOffset = getOffset(baseDocument, namespaceScope, parserResult, importData.caretPosition); List<UsePart> useParts = new ArrayList<>(); Collection<? extends GroupUseScope> declaredGroupUses = namespaceScope.getDeclaredGroupUses(); for (GroupUseScope groupUseElement : declaredGroupUses) { @@ -148,7 +145,7 @@ public class FixUsesPerformer { } } replaceUnimportedItems(); - String insertString = createInsertString(useParts); + String insertString = createInsertString(useParts, shouldAppendLineAfter(startOffset)); // avoid being recognized as a modified file if (insertString.isEmpty()) { StatusDisplayer.getDefault().setStatusText(Bundle.FixUsesPerformer_noChanges()); @@ -156,6 +153,15 @@ public class FixUsesPerformer { editList.replace(startOffset, 0, insertString, false, 0); } } + + private boolean shouldAppendLineAfter(int lineOffset) { + try { + return LineDocumentUtils.getNextNonWhitespace(baseDocument, lineOffset, LineDocumentUtils.getLineEnd(baseDocument, lineOffset)) != -1; + } catch (BadLocationException ex) { + Exceptions.printStackTrace(ex); + } + return false; + } private void replaceUnimportedItems() { for (ImportData.DataItem dataItem : importData.getItemsToReplace()) { @@ -244,7 +250,7 @@ public class FixUsesPerformer { return result; } - private String createInsertString(final List<UsePart> useParts) { + private String createInsertString(final List<UsePart> useParts, boolean shouldAppendLineAfter) { StringBuilder insertString = new StringBuilder(); Collections.sort(useParts); if (useParts.size() > 0) { @@ -265,6 +271,9 @@ public class FixUsesPerformer { } else { insertString.append(createStringForCommonUse(useParts)); } + if (shouldAppendLineAfter) { + insertString.append(NEW_LINE); + } return insertString.toString(); } @@ -411,16 +420,104 @@ public class FixUsesPerformer { return result.toString(); } - private void processExistingUses() { - ExistingUseStatementVisitor visitor = new ExistingUseStatementVisitor(); + private int processExistingUses(int caretPosition) { + CheckVisitor visitor = new CheckVisitor(); Program program = parserResult.getProgram(); if (program != null) { program.accept(visitor); } + + // import has been working properly only for first default namespace + // or for namespace under caret, so we should not remove USES in other + // namespaces in the same file and use only current scope + int useScopeStart = namespaceScope.getBlockRange().getStart(); + int useScopeEnd = namespaceScope.getBlockRange().getEnd(); + + List<NamespaceDeclaration> globalNamespaceDeclarations = visitor.getGlobalNamespaceDeclarations(); + if (namespaceScope.isDefaultNamespace()) { + // this is check for case when we don't have namespace declaration in file + // such <?php but tag could be not on the first line, also we put statemens + // after phpdoc blocks due to PSR/PER + if (globalNamespaceDeclarations.isEmpty()) { + baseDocument.readLock(); + try { + TokenSequence<? extends PHPTokenId> ts = LexUtilities.getPositionedSequence(baseDocument, namespaceScope.getBlockRange().getEnd()); + if (ts != null) { + LexUtilities.findPreviousToken(ts, Arrays.asList(PHPTokenId.PHP_OPENTAG, PHPTokenId.PHPDOC_COMMENT_END)); + if (ts.token().id().equals(PHPTokenId.PHP_OPENTAG) || ts.token().id().equals(PHPTokenId.PHPDOC_COMMENT_END)) { + useScopeStart = ts.offset() + ts.token().length() + 1; + } + } + } finally { + baseDocument.readUnlock(); + } + } else { + // only for case when caret outside of global namespace nested + // in defalut global namespace such as <?php ^ namespace {} + if (!globalNamespaceDeclarations.isEmpty()) { + useScopeStart = globalNamespaceDeclarations.get(0).getBody().getStartOffset() + 1; + useScopeEnd = globalNamespaceDeclarations.get(0).getBody().getEndOffset(); + } + // there is wrong blockRange computing in parserResult for global + // namespaces so we need to check carret bounds by ourself, + // especially because there is could be more than one global namespace + for (NamespaceDeclaration globalNamespace : globalNamespaceDeclarations) { + if (globalNamespace.getStartOffset() <= caretPosition + && caretPosition <= globalNamespace.getEndOffset()) { + useScopeStart = globalNamespace.getBody().getStartOffset() + 1; // +1: { + useScopeEnd = globalNamespace.getBody().getEndOffset(); + break; + } + } + } + } else if (useScopeStart > 0) { + //because when semicolon in the end of a namespace, the block starts + //after semicolon, but for brace it starts before curly open + //we can't just add +1 because of such case <?php namespace NS;?> + baseDocument.readLock(); + try { + if (LexUtilities.getTokenChar(baseDocument, useScopeStart) == CURLY_OPEN) { + useScopeStart++; + } + } finally { + baseDocument.readUnlock(); + } + } + + int lastUseOffset = useScopeStart; for (OffsetRange offsetRange : visitor.getUsedRanges()) { + if (offsetRange.getStart() < useScopeStart || offsetRange.getEnd() > useScopeEnd) { + continue; + } int startOffset = getOffsetWithoutLeadingWhitespaces(offsetRange.getStart()); editList.replace(startOffset, offsetRange.getEnd() - startOffset, EMPTY_STRING, false, 0); + lastUseOffset = offsetRange.getEnd() > lastUseOffset ? offsetRange.getEnd() : lastUseOffset; + } + + // because only declare(strict_types=1) should go first, but declare(ticks=1) could be everywhere + // we have to restrict declare start offset to prevent wrong USE placement after declare in cases such + // function { declare(ticks=1); } or class A { puclic function fn () { declare(ticks=1); } } + // in the feature it would be better to have DeclareStatmentScope for that + int maxDeclareOffset = namespaceScope.getElements().isEmpty() ? useScopeEnd : namespaceScope.getElements().get(0).getOffset(); + // NETBEANS-4978 check whether declare statemens exist + // e.g. in the following case, insert the code(use statements) after the declare statement + // declare (strict_types=1); + // class TestClass + // { + // public function __construct() + // { + // $test = new Foo(); + // } + // } + for (DeclareStatement declareStatement : visitor.getDeclareStatements()) { + if (maxDeclareOffset < declareStatement.getStartOffset()) { + break; + } + lastUseOffset = Math.max(lastUseOffset, declareStatement.getEndOffset()); } + + + return lastUseOffset; } private int getOffsetWithoutLeadingWhitespaces(final int startOffset) { @@ -440,79 +537,12 @@ public class FixUsesPerformer { return result; } - private static int getOffset(BaseDocument baseDocument, NamespaceScope namespaceScope, PHPParseResult parserResult, int caretPosition) { - try { - ModelElement lastSingleUse = getLastUse(namespaceScope, false); - ModelElement lastGroupUse = getLastUse(namespaceScope, true); - if (lastSingleUse != null - && lastGroupUse != null) { - if (lastSingleUse.getOffset() > lastGroupUse.getOffset()) { - return LineDocumentUtils.getLineEnd(baseDocument, lastSingleUse.getOffset()); - } - // XXX is this correct? - return LineDocumentUtils.getLineEnd(baseDocument, lastGroupUse.getNameRange().getEnd()); - } - if (lastSingleUse != null) { - return LineDocumentUtils.getLineEnd(baseDocument, lastSingleUse.getOffset()); - } - if (lastGroupUse != null) { - // XXX is this correct? - return LineDocumentUtils.getLineEnd(baseDocument, lastGroupUse.getNameRange().getEnd()); - } - // NETBEANS-4978 check whether declare statemens exist - // e.g. in the following case, insert the code(use statements) after the declare statement - // declare (strict_types=1); - // class TestClass - // { - // public function __construct() - // { - // $test = new Foo(); - // } - // } - int offset = LineDocumentUtils.getLineEnd(baseDocument, namespaceScope.getOffset()); - CheckVisitor checkVisitor = new CheckVisitor(); - parserResult.getProgram().accept(checkVisitor); - if (namespaceScope.isDefaultNamespace()) { - List<NamespaceDeclaration> globalNamespaceDeclarations = checkVisitor.getGlobalNamespaceDeclarations(); - if (!globalNamespaceDeclarations.isEmpty()) { - offset = globalNamespaceDeclarations.get(0).getBody().getStartOffset() + 1; // +1: { - } - for (NamespaceDeclaration globalNamespace : globalNamespaceDeclarations) { - if (globalNamespace.getStartOffset() <= caretPosition - && caretPosition <= globalNamespace.getEndOffset()) { - offset = globalNamespace.getBody().getStartOffset() + 1; // +1: { - break; - } - } - } - for (DeclareStatement declareStatement : checkVisitor.getDeclareStatements()) { - offset = Math.max(offset, declareStatement.getEndOffset()); - } - return offset; - } catch (BadLocationException ex) { - Exceptions.printStackTrace(ex); - } - return 0; - } - - @CheckForNull - private static ModelElement getLastUse(NamespaceScope namespaceScope, boolean group) { - ModelElement offsetElement = null; - Collection<? extends Scope> declaredUses = group ? namespaceScope.getDeclaredGroupUses() : namespaceScope.getDeclaredSingleUses(); - for (Scope useElement : declaredUses) { - if (offsetElement == null - || offsetElement.getOffset() < useElement.getOffset()) { - offsetElement = useElement; - } - } - return offsetElement; - } - //~ inner classes private static class CheckVisitor extends DefaultVisitor { private List<DeclareStatement> declareStatements = new ArrayList<>(); private List<NamespaceDeclaration> globalNamespaceDeclarations = new ArrayList<>(); + private final List<OffsetRange> usedRanges = new LinkedList<>(); public List<DeclareStatement> getDeclareStatements() { return Collections.unmodifiableList(declareStatements); @@ -522,12 +552,25 @@ public class FixUsesPerformer { return Collections.unmodifiableList(globalNamespaceDeclarations); } + public List<OffsetRange> getUsedRanges() { + return Collections.unmodifiableList(usedRanges); + } + + @Override + public void visit(UseStatement node) { + if (CancelSupport.getDefault().isCancelled()) { + return; + } + usedRanges.add(new OffsetRange(node.getStartOffset(), node.getEndOffset())); + super.visit(node); + } + @Override public void visit(DeclareStatement node) { if (CancelSupport.getDefault().isCancelled()) { return; } - declareStatements.add(node); + declareStatements.add(node); super.visit(node); } @@ -678,20 +721,6 @@ public class FixUsesPerformer { } } - private static class ExistingUseStatementVisitor extends DefaultVisitor { - - private final List<OffsetRange> usedRanges = new LinkedList<>(); - - public List<OffsetRange> getUsedRanges() { - return Collections.unmodifiableList(usedRanges); - } - - @Override - public void visit(UseStatement node) { - usedRanges.add(new OffsetRange(node.getStartOffset(), node.getEndOffset())); - } - } - private static class UsePart implements Comparable<UsePart> { enum Type { diff --git a/php/php.editor/test/unit/data/testfiles/actions/testGH5578/01/B.php b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/01/B.php new file mode 100644 index 0000000000..98ddf96c9a --- /dev/null +++ b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/01/B.php @@ -0,0 +1,23 @@ +<?php +/* + * 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. + */ +namespace NS1; + +class B +{} \ No newline at end of file diff --git a/php/php.editor/test/unit/data/testfiles/actions/testGH5578/01/testGH5578_01.php b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/01/testGH5578_01.php new file mode 100644 index 0000000000..480ab4a310 --- /dev/null +++ b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/01/testGH5578_01.php @@ -0,0 +1,36 @@ +<?php declare (ticks=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. + */ +class A +{ + + public function __construct() + { + // test + $test = new \NS1\B(); + } + + public function test(?\NS1\B $foo): ?\NS1\B + { + return null; + } +} \ No newline at end of file diff --git a/php/php.editor/test/unit/data/testfiles/actions/testGH5578/01/testGH5578_01.php.fixUses b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/01/testGH5578_01.php.fixUses new file mode 100644 index 0000000000..482ac02410 --- /dev/null +++ b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/01/testGH5578_01.php.fixUses @@ -0,0 +1,38 @@ +<?php declare (ticks=1) { + + +} + +use NS1\B; +/* + * 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. + */ +class A +{ + + public function __construct() + { + // test + $test = new B(); + } + + public function test(?B $foo): ?B + { + return null; + } +} diff --git a/php/php.editor/test/unit/data/testfiles/actions/testGH5578/02/B.php b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/02/B.php new file mode 100644 index 0000000000..98ddf96c9a --- /dev/null +++ b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/02/B.php @@ -0,0 +1,23 @@ +<?php +/* + * 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. + */ +namespace NS1; + +class B +{} \ No newline at end of file diff --git a/php/php.editor/test/unit/data/testfiles/actions/testGH5578/02/testGH5578_02.php b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/02/testGH5578_02.php new file mode 100644 index 0000000000..dde619a2e9 --- /dev/null +++ b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/02/testGH5578_02.php @@ -0,0 +1,35 @@ +<?php +/* + * 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. + */ +// test +?> + +<!DOCTYPE html> +<html> + <head> + <meta charset="UTF-8"> + <title></title> + </head> + <body> + <?php + + new \NS1\B; + ?> + </body> +</html> \ No newline at end of file diff --git a/php/php.editor/test/unit/data/testfiles/actions/testGH5578/02/testGH5578_02.php.fixUses b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/02/testGH5578_02.php.fixUses new file mode 100644 index 0000000000..198d4215b0 --- /dev/null +++ b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/02/testGH5578_02.php.fixUses @@ -0,0 +1,37 @@ +<?php +/* + * 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. + */ +// test +?> + +<!DOCTYPE html> +<html> + <head> + <meta charset="UTF-8"> + <title></title> + </head> + <body> + <?php + + +use NS1\B; + new B; + ?> + </body> +</html> \ No newline at end of file diff --git a/php/php.editor/test/unit/data/testfiles/actions/testGH5578/03/testGH5578_03.php b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/03/testGH5578_03.php new file mode 100644 index 0000000000..7552ceadd1 --- /dev/null +++ b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/03/testGH5578_03.php @@ -0,0 +1,42 @@ +<?php +/* + * 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. + */ + +?> + +<!DOCTYPE html> +<html> + <head> + <meta charset="UTF-8"> + <title></title> + </head> + <body> + <? namespace NS1;?> + + <?php // test + new A; + new B; + ?> + </body> +</html> + +<?php namespace NS2 { + class A {} + class B {} +} diff --git a/php/php.editor/test/unit/data/testfiles/actions/testGH5578/03/testGH5578_03.php.fixUses b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/03/testGH5578_03.php.fixUses new file mode 100644 index 0000000000..f20d123542 --- /dev/null +++ b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/03/testGH5578_03.php.fixUses @@ -0,0 +1,46 @@ +<?php +/* + * 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. + */ + +?> + +<!DOCTYPE html> +<html> + <head> + <meta charset="UTF-8"> + <title></title> + </head> + <body> + <? namespace NS1; + +use NS2\A; +use NS2\B; +?> + + <?php // test + new A; + new B; + ?> + </body> +</html> + +<?php namespace NS2 { + class A {} + class B {} +} diff --git a/php/php.editor/test/unit/data/testfiles/actions/testGH5578/04/testGH5578_04.php b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/04/testGH5578_04.php new file mode 100644 index 0000000000..666b7396cf --- /dev/null +++ b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/04/testGH5578_04.php @@ -0,0 +1,43 @@ +<?php +/* + * 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. + */ + +// test +namespace NS1; /* + * + */ + +class A +{ + + public function __construct() + { + $test = new B(); + } + + public function test(?B $foo): ?B + { + return null; + } + +} + +namespace NS2; + +class B {} \ No newline at end of file diff --git a/php/php.editor/test/unit/data/testfiles/actions/testGH5578/04/testGH5578_04.php.fixUses b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/04/testGH5578_04.php.fixUses new file mode 100644 index 0000000000..5ea80c9429 --- /dev/null +++ b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/04/testGH5578_04.php.fixUses @@ -0,0 +1,46 @@ +<?php +/* + * 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. + */ + +// test +namespace NS1; + +use NS2\B; + /* + * + */ + +class A +{ + + public function __construct() + { + $test = new B(); + } + + public function test(?B $foo): ?B + { + return null; + } + +} + +namespace NS2; + +class B {} \ No newline at end of file diff --git a/php/php.editor/test/unit/data/testfiles/actions/testGH5578/05/testGH5578_05.php b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/05/testGH5578_05.php new file mode 100644 index 0000000000..787884c2cc --- /dev/null +++ b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/05/testGH5578_05.php @@ -0,0 +1,44 @@ +<?php +/* + * 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. + */ + +// test +namespace NS1; + +class A +{ + + public function __construct() + { + declare (ticks=1) { + + } + $test = new B(); + } + + public function test(?B $foo): ?B + { + return null; + } + +} + +namespace NS2; + +class B {} \ No newline at end of file diff --git a/php/php.editor/test/unit/data/testfiles/actions/testGH5578/05/testGH5578_05.php.fixUses b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/05/testGH5578_05.php.fixUses new file mode 100644 index 0000000000..44088445a1 --- /dev/null +++ b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/05/testGH5578_05.php.fixUses @@ -0,0 +1,46 @@ +<?php +/* + * 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. + */ + +// test +namespace NS1; + +use NS2\B; + +class A +{ + + public function __construct() + { + declare (ticks=1) { + + } + $test = new B(); + } + + public function test(?B $foo): ?B + { + return null; + } + +} + +namespace NS2; + +class B {} \ No newline at end of file diff --git a/php/php.editor/test/unit/data/testfiles/actions/testGH5578/06/testGH5578_06.php b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/06/testGH5578_06.php new file mode 100644 index 0000000000..9b0b591baf --- /dev/null +++ b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/06/testGH5578_06.php @@ -0,0 +1,49 @@ +<?php +/* + * 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. + */ + +// test +namespace { + + class A { + public function fn() { + new \NS2\B; + } + } +} + +namespace NS2 { + +use NS3\C; + + class B { + public function fn() { + new C; + } + } +} + +namespace NS3 { + + class C { + public function fn() { + new \NS2\B; + } + } +} diff --git a/php/php.editor/test/unit/data/testfiles/actions/testGH5578/06/testGH5578_06.php.fixUses b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/06/testGH5578_06.php.fixUses new file mode 100644 index 0000000000..1e37a361b0 --- /dev/null +++ b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/06/testGH5578_06.php.fixUses @@ -0,0 +1,51 @@ +<?php +/* + * 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. + */ + +// test +namespace { + +use NS2\B; + + class A { + public function fn() { + new B; + } + } +} + +namespace NS2 { + +use NS3\C; + + class B { + public function fn() { + new C; + } + } +} + +namespace NS3 { + + class C { + public function fn() { + new \NS2\B; + } + } +} diff --git a/php/php.editor/test/unit/data/testfiles/actions/testGH5578/07/testGH5578_07.php b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/07/testGH5578_07.php new file mode 100644 index 0000000000..2b3b543287 --- /dev/null +++ b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/07/testGH5578_07.php @@ -0,0 +1,49 @@ +<?php +/* + * 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. + */ +namespace NS1; +// test +declare(ticks=1) { + +} + +declare(ticks=2) { + +} + +class A +{ + + public function __construct() + { + declare(ticks=2) { + + } + $test = new \NS2\B(); + } + + public function test(?\NS2\B $foo): ?\NS2\B + { + return null; + } +} + +namespace NS2; + +class B {} \ No newline at end of file diff --git a/php/php.editor/test/unit/data/testfiles/actions/testGH5578/07/testGH5578_07.php.fixUses b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/07/testGH5578_07.php.fixUses new file mode 100644 index 0000000000..a018f1d09c --- /dev/null +++ b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/07/testGH5578_07.php.fixUses @@ -0,0 +1,51 @@ +<?php +/* + * 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. + */ +namespace NS1; +// test +declare(ticks=1) { + +} + +declare(ticks=2) { + +} + +use NS2\B; + +class A +{ + + public function __construct() + { + declare(ticks=2) { + + } + $test = new B(); + } + + public function test(?B $foo): ?B + { + return null; + } +} + +namespace NS2; + +class B {} \ No newline at end of file diff --git a/php/php.editor/test/unit/data/testfiles/actions/testGH5578/08/B.php b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/08/B.php new file mode 100644 index 0000000000..98ddf96c9a --- /dev/null +++ b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/08/B.php @@ -0,0 +1,23 @@ +<?php +/* + * 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. + */ +namespace NS1; + +class B +{} \ No newline at end of file diff --git a/php/php.editor/test/unit/data/testfiles/actions/testGH5578/08/testGH5578_08.php b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/08/testGH5578_08.php new file mode 100644 index 0000000000..1dadade75b --- /dev/null +++ b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/08/testGH5578_08.php @@ -0,0 +1,41 @@ +<?php +/* + * 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. + */ +// test +?> + +<!DOCTYPE html> +<html> + <head> + <meta charset="UTF-8"> + <title></title> + </head> + <body> + <?php + declare(ticks=1); + + /** + * this is phpDoc block which go after declare + * and use statement should go after docBlock + */ + + new \NS1\B; + ?> + </body> +</html> \ No newline at end of file diff --git a/php/php.editor/test/unit/data/testfiles/actions/testGH5578/08/testGH5578_08.php.fixUses b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/08/testGH5578_08.php.fixUses new file mode 100644 index 0000000000..b40d673865 --- /dev/null +++ b/php/php.editor/test/unit/data/testfiles/actions/testGH5578/08/testGH5578_08.php.fixUses @@ -0,0 +1,43 @@ +<?php +/* + * 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. + */ +// test +?> + +<!DOCTYPE html> +<html> + <head> + <meta charset="UTF-8"> + <title></title> + </head> + <body> + <?php + declare(ticks=1); + + /** + * this is phpDoc block which go after declare + * and use statement should go after docBlock + */ + + +use NS1\B; + new B; + ?> + </body> +</html> \ No newline at end of file diff --git a/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/actions/FixUsesPerformerTest.java b/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/actions/FixUsesPerformerTest.java index 7518c873e7..0385913a25 100644 --- a/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/actions/FixUsesPerformerTest.java +++ b/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/actions/FixUsesPerformerTest.java @@ -351,6 +351,56 @@ public class FixUsesPerformerTest extends PHPTestBase { Options options = new Options(false, false, false, false, true); performTest("// test^", createSelections(selections, ItemVariant.Type.CLASS), true, options); } + + public void testGH5578_01() throws Exception { + String[] selections = new String[] {"\\NS1\\B"}; + Options options = new Options(false, false, false, false, true); + performTest("// test^", createSelections(selections, ItemVariant.Type.CLASS), true, options); + } + + public void testGH5578_02() throws Exception { + String[] selections = new String[] {"\\NS1\\B"}; + Options options = new Options(false, false, false, false, true); + performTest("// test^", createSelections(selections, ItemVariant.Type.CLASS), true, options); + } + + public void testGH5578_03() throws Exception { + List<Selection> selections = new ArrayList<>(); + selections.add(new Selection("\\NS2\\A", ItemVariant.Type.CLASS)); + selections.add(new Selection("\\NS2\\B", ItemVariant.Type.CLASS)); + Options options = new Options(false, false, false, false, true); + performTest("// test^", selections, true, options); + } + + public void testGH5578_04() throws Exception { + String[] selections = new String[] {"\\NS2\\B"}; + Options options = new Options(false, false, false, false, true); + performTest("// test^", createSelections(selections, ItemVariant.Type.CLASS), true, options); + } + + public void testGH5578_05() throws Exception { + String[] selections = new String[] {"\\NS2\\B"}; + Options options = new Options(false, false, false, false, true); + performTest("// test^", createSelections(selections, ItemVariant.Type.CLASS), true, options); + } + + public void testGH5578_06() throws Exception { + String[] selections = new String[] {"\\NS2\\B"}; + Options options = new Options(false, false, false, false, true); + performTest("// test^", createSelections(selections, ItemVariant.Type.CLASS), true, options); + } + + public void testGH5578_07() throws Exception { + String[] selections = new String[] {"\\NS2\\B"}; + Options options = new Options(false, false, false, false, true); + performTest("// test^", createSelections(selections, ItemVariant.Type.CLASS), true, options); + } + + public void testGH5578_08() throws Exception { + String[] selections = new String[] {"\\NS1\\B"}; + Options options = new Options(false, false, false, false, true); + performTest("// test^", createSelections(selections, ItemVariant.Type.CLASS), true, options); + } private String getTestResult(final String fileName, final String caretLine, final List<Selection> selections, final boolean removeUnusedUses, final Options options) throws Exception { FileObject testFile = getTestFile(fileName); --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@netbeans.apache.org For additional commands, e-mail: commits-h...@netbeans.apache.org For further information about the NetBeans mailing lists, visit: https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists