Skip to content

Commit

Permalink
Fix "Fix Imports" issue with declare statements apache#5578
Browse files Browse the repository at this point in the history
- apache#5578

Example:
```php
<?php
namespace NS1;

declare(ticks=1) {
    $test = 1;
}
declare(ticks=2) {
    $test = 1;
}
class DeclareTest1 {
    public function test() {
        declare(ticks=2) {

        }
        $test = new \NS2\DeclareTest2;
    }
}
```

Before:
```php
<?php
namespace NS1;

declare(ticks=1) {
    $test = 1;
}
use NS2\DeclareTest2;
declare(ticks=2) {
    $test = 1;
}
class DeclareTest1 {
    public function test() {
        declare(ticks=2) {

        }
        $test = new DeclareTest2;
    }
}
```

After:
```php
<?php
namespace NS1;

declare(ticks=1) {
    $test = 1;
}
declare(ticks=2) {
    $test = 1;
}

use NS2\DeclareTest2;

class DeclareTest1 {
    public function test() {
        declare(ticks=2) {

        }
        $test = new DeclareTest2;
    }
}
```
  • Loading branch information
junichi11 committed Jul 11, 2023
1 parent 3d86f39 commit 85eed67
Show file tree
Hide file tree
Showing 8 changed files with 305 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -590,9 +590,7 @@ private static int processDeclareStatementsOffset(NamespaceScope namespaceScope,
// function foo() {
// declare(ticks=1) {}
// }
int maxDeclareOffset = namespaceScope.getElements().isEmpty()
? namespaceScope.getBlockRange().getEnd()
: namespaceScope.getElements().get(0).getOffset();
int maxDeclareOffset = getMaxDeclareOffset(namespaceScope, checkVisitor);
for (DeclareStatement declareStatement : checkVisitor.getDeclareStatements()) {
if (maxDeclareOffset < declareStatement.getStartOffset()) {
break;
Expand All @@ -602,6 +600,47 @@ private static int processDeclareStatementsOffset(NamespaceScope namespaceScope,
return result;
}

private static int getMaxDeclareOffset(NamespaceScope namespaceScope, CheckVisitor checkVisitor) {
int maxDeclareOffset = namespaceScope.getBlockRange().getEnd();
if (!namespaceScope.getElements().isEmpty()) {
for (ModelElement element : namespaceScope.getElements()) {
if (isInDeclare(element.getOffset(), checkVisitor.getDeclareStatements())) {
maxDeclareOffset = getDeclareEndPosition(element.getOffset(), checkVisitor.getDeclareStatements());
continue;
}
maxDeclareOffset = element.getOffset();
break;
}
}
return maxDeclareOffset;
}

private static boolean isInDeclare(int offset, List<DeclareStatement> declareStatements) {
// e.g.
// declare(ticks=1) {
// $test = 1; // is this element in declare?
// }
for (DeclareStatement declareStatement : declareStatements) {
if (isInDeclare(offset, declareStatement)) {
return true;
}
}
return false;
}

private static boolean isInDeclare(int offset, DeclareStatement declareStatement) {
return declareStatement.getStartOffset() < offset && offset < declareStatement.getEndOffset();
}

private static int getDeclareEndPosition(int offset, List<DeclareStatement> declareStatements) {
for (DeclareStatement declareStatement : declareStatements) {
if (isInDeclare(offset, declareStatement)) {
return declareStatement.getEndOffset();
}
}
return -1;
}

@CheckForNull
private static ModelElement getLastUse(NamespaceScope namespaceScope, boolean group) {
ModelElement offsetElement = null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?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;

declare(ticks=1) {
$test = 1;
}
declare(ticks=2) {
$test = 1;
}

class DeclareTest1 {
public function test() {
declare(ticks=2) {

}
$test = new \NS2\DeclareTest2;
}
}

namespace NS2;

class DeclareTest2 {}
Original file line number Diff line number Diff line change
@@ -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.
*/
namespace NS1;

declare(ticks=1) {
$test = 1;
}
declare(ticks=2) {
$test = 1;
}

use NS2\DeclareTest2;

class DeclareTest1 {
public function test() {
declare(ticks=2) {

}
$test = new DeclareTest2;
}
}

namespace NS2;

class DeclareTest2 {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?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;

declare(ticks=1) {
}
declare(ticks=2) {
$test = 1;
}

class DeclareTest1 {
public function test() {
declare(ticks=2) {

}
$test = new \NS2\DeclareTest2;
}
}

namespace NS2;

class DeclareTest2 {}
Original file line number Diff line number Diff line change
@@ -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.
*/
namespace NS1;

declare(ticks=1) {
}
declare(ticks=2) {
$test = 1;
}

use NS2\DeclareTest2;

class DeclareTest1 {
public function test() {
declare(ticks=2) {

}
$test = new DeclareTest2;
}
}

namespace NS2;

class DeclareTest2 {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?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;

declare(ticks=1) {
$test = 1;
}
declare(ticks=2) {
}

class DeclareTest1 {
public function test() {
declare(ticks=2) {

}
$test = new \NS2\DeclareTest2;
}
}

namespace NS2;

class DeclareTest2 {}
Original file line number Diff line number Diff line change
@@ -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.
*/
namespace NS1;

declare(ticks=1) {
$test = 1;
}
declare(ticks=2) {
}

use NS2\DeclareTest2;

class DeclareTest1 {
public function test() {
declare(ticks=2) {

}
$test = new DeclareTest2;
}
}

namespace NS2;

class DeclareTest2 {}
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,27 @@ public void testGH5578_declare02() throws Exception {
performTest("^// test", selections, true, options);
}

public void testGH5578_declare03() throws Exception {
List<Selection> selections = new ArrayList<>();
selections.add(new Selection("\\NS2\\DeclareTest2", ItemVariant.Type.CLASS));
Options options = new Options.Builder(PhpVersion.PHP_81).build();
performTest("class DeclareTest1 ^{", selections, true, options);
}

public void testGH5578_declare04() throws Exception {
List<Selection> selections = new ArrayList<>();
selections.add(new Selection("\\NS2\\DeclareTest2", ItemVariant.Type.CLASS));
Options options = new Options.Builder(PhpVersion.PHP_81).build();
performTest("class DeclareTest1 ^{", selections, true, options);
}

public void testGH5578_declare05() throws Exception {
List<Selection> selections = new ArrayList<>();
selections.add(new Selection("\\NS2\\DeclareTest2", ItemVariant.Type.CLASS));
Options options = new Options.Builder(PhpVersion.PHP_81).build();
performTest("class DeclareTest1 ^{", selections, 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);

Expand Down

0 comments on commit 85eed67

Please sign in to comment.