Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(java): add a method to copy a java method and rename it #1162

Merged
merged 27 commits into from
Jul 23, 2021
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
f4304f5
chore(java): add a method to copy a java method and rename it
Neenu1995 Jul 19, 2021
56c9c70
chore: fix typo
Neenu1995 Jul 19, 2021
de69a1e
chore: fix lint
Neenu1995 Jul 19, 2021
0f3725a
chore: fix lint in java.py
Neenu1995 Jul 19, 2021
6efab3e
chore: fix lint in tranforms.py
Neenu1995 Jul 19, 2021
9a5046f
chore: add method to deprecate java methods
Neenu1995 Jul 19, 2021
c4ced1f
chore: fix lint
Neenu1995 Jul 19, 2021
64b7c50
chore: fix deprecate method test
Neenu1995 Jul 19, 2021
6ea80ad
chore: minor chnages
Neenu1995 Jul 19, 2021
333413b
chore: fix year in Golden files
Neenu1995 Jul 19, 2021
507c868
chore: fix curly brackets
Neenu1995 Jul 19, 2021
f1425d9
Merge branch 'master' into duplicate-method-java
Neenu1995 Jul 20, 2021
10c9c64
chore: handle pre-existing javadocs and annotations
Neenu1995 Jul 20, 2021
30238c0
chore: fix deprecation method
Neenu1995 Jul 21, 2021
a5be64f
Merge branch 'master' into duplicate-method-java
Neenu1995 Jul 21, 2021
e3a3c43
chore: fix lint
Neenu1995 Jul 21, 2021
ebcfb2a
chore: fix lint
Neenu1995 Jul 21, 2021
17604f9
chore: fix lint
Neenu1995 Jul 21, 2021
44978e7
chore: fix lint
Neenu1995 Jul 21, 2021
27d3145
chore: fix lint
Neenu1995 Jul 21, 2021
2d8b00a
chore: fix cornercase in deprecate_method
Neenu1995 Jul 21, 2021
e8dd6df
chore: fix code formatting
Neenu1995 Jul 21, 2021
8d9fe26
chore: minor fix
Neenu1995 Jul 21, 2021
a4b726a
chore: fix formating
Neenu1995 Jul 22, 2021
bc01688
Merge branch 'master' into duplicate-method-java
Neenu1995 Jul 22, 2021
75e2fbe
fix: fix the deprecation formatting (#1164)
chingor13 Jul 23, 2021
c06ff63
refactor: alternative of splitting into add_javadoc and annotate_meth…
chingor13 Jul 23, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ venv.bak/
.vscode/
.settings/
.project
.idea/

# synthtool artifacts
working_repo/
Expand Down
140 changes: 140 additions & 0 deletions synthtool/languages/java.py
Original file line number Diff line number Diff line change
Expand Up @@ -572,3 +572,143 @@ class Example {
for line in lines:
# print(line)
fp.write(line)


def copy_and_rename_method(filename: str, signature: str, before: str, after: str):
"""Helper to make a copy an entire method and rename it.

Goes line-by-line to detect the start of the block. Determines
the end of the block by a closing brace at the same indentation
level. This requires the file to be correctly formatted.
Neenu1995 marked this conversation as resolved.
Show resolved Hide resolved
The method is copied over and renamed in the method signature.
The calls to both methods are separate and unaffected.

Example: consider the following class:

class Example {
public void main(String[] args) {
System.out.println("Hello World");
}

public String foo() {
return "bar";
}
}

To copy and rename the `main` method above, use:

copy_and_rename_method('path/to/file', 'public void main(String[] args)',
'main', 'foo1')

Args:
filename (str): Path to source file
signature (str): Full signature of the method to remove. Example:
`public void main(String[] args)`.
before (str): name of the method to be copied
after (str): new name of the copied method
"""
lines = []
method = []
leading_regex = None
with open(filename, "r") as fp:
line = fp.readline()
while line:
# for each line, try to find the matching
regex = re.compile("(\\s*)" + re.escape(signature) + ".*")
match = regex.match(line)
if match:
leading_regex = re.compile(match.group(1) + "}")
lines.append(line)
method.append(line.replace(before, after))
line = fp.readline()
continue

lines.append(line)
# not in a ignore block - preserve the line
if leading_regex:
method.append(line)
else:
line = fp.readline()
continue

# detect the closing tag based on the leading spaces
match = leading_regex.match(line)
if match:
# block is closed, resume capturing content
leading_regex = None
lines.append("\n")
lines.extend(method)

line = fp.readline()

with open(filename, "w") as fp:
for line in lines:
# print(line)
fp.write(line)


def deprecate_method(filename: str, signature: str, alternative: str):
"""Helper to deprecate a method.

Goes line-by-line to detect the start of the block.
Then adds the deprecation comment before the method signature.
The @Deprecation annotation is also added.

Example: consider the following class:

class Example {
public void main(String[] args) {
System.out.println("Hello World");
}

public String foo() {
return "bar";
}
}

To deprecate the `main` method 6above, use:

deprecate_method('path/to/file', 'public void main(String[] args)',
DEPRECATION_WARNING.format(new_method="foo"))

Args:
filename (str): Path to source file
signature (str): Full signature of the method to remove. Example:
`public void main(String[] args)`.
alternative: DEPRECATION WARNING: multiline javadoc comment with user
specified leading open/close comment tags
"""
lines: List[str] = []
annotations: List[str] = []
with open(filename, "r") as fp:
line = fp.readline()
while line:
# for each line, try to find the matching
regex = re.compile("(\\s*)" + re.escape(signature) + ".*")
match = regex.match(line)
if match:
last_line = lines.pop()
if "*/" in last_line:
alternative = "\n".join(alternative.splitlines()[1:])
lines.extend(alternative)
elif "@" in last_line:
while "@" in last_line:
if "@Deprecated" not in last_line:
annotations.insert(0, last_line)
last_line = lines.pop()
if "*/" in last_line:
alternative = "\n".join(alternative.splitlines()[1:])
lines.extend(alternative)
lines.extend(annotations)
else:
lines.extend(last_line)
lines.extend(alternative)
lines.append("@Deprecated\n")
lines.append(line)
line = fp.readline()

with open(filename, "w") as fp:
for line in lines:
# print(line)
fp.write(line)
format_code("/".join(filename.split("/")[:-1]))
52 changes: 52 additions & 0 deletions tests/test_language_java.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,58 @@ def test_remove_method():
)


def test_copy_and_rename_method():
with tempfile.TemporaryDirectory() as tempdir:
shutil.copyfile(
"tests/testdata/SampleClass.java", tempdir + "/SampleClass.java"
)

java.copy_and_rename_method(
tempdir + "/SampleClass.java", "public static void foo()", "foo", "foobar"
)
java.copy_and_rename_method(
tempdir + "/SampleClass.java", "public void asdf()", "asdf", "xyz"
)
assert_matches_golden(
"tests/testdata/SampleCopyMethodGolden.java", tempdir + "/SampleClass.java"
)


def test_deprecate_method():
with tempfile.TemporaryDirectory() as tempdir:
shutil.copyfile(
"tests/testdata/SampleClass.java", tempdir + "/SampleClass.java"
)
DEPRECATION_WARNING = """ /*
* @deprecated This method will be removed in the next major version.
* Use {{@link #{new_method}()}} instead
*/
"""
ADDITIONAL_COMMENT = """ /*
* {new_method} has the same functionality as foobar.
*/
"""
java.copy_and_rename_method(
tempdir + "/SampleClass.java", "public static void foo()", "foo", "foobar"
)
java.deprecate_method(
tempdir + "/SampleClass.java",
"public static void foobar()",
DEPRECATION_WARNING.format(new_method="foo"),
)
# adding a comment when a javadoc and annotation already exists
java.deprecate_method(
tempdir + "/SampleClass.java",
"public static void foobar()",
ADDITIONAL_COMMENT.format(new_method="foo"),
)

assert_matches_golden(
"tests/testdata/SampleDeprecateMethodGolden.java",
tempdir + "/SampleClass.java",
)


def test_fix_proto_license():
with tempfile.TemporaryDirectory() as tempdir:
temppath = Path(tempdir).resolve()
Expand Down
37 changes: 37 additions & 0 deletions tests/testdata/SampleCopyMethodGolden.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright 2020 Google LLC
Neenu1995 marked this conversation as resolved.
Show resolved Hide resolved
*
* Licensed 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
*
* https://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 dlp;

class ExampleClass {
public static void foo() {
System.out.println("bar");
}

public static void foobar() {
System.out.println("bar");
}

public static class InnerClass {
public void asdf() {
System.out.println("qwer");
}

public void xyz() {
System.out.println("qwer");
}
}
}
39 changes: 39 additions & 0 deletions tests/testdata/SampleDeprecateMethodGolden.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright 2020 Google LLC
Neenu1995 marked this conversation as resolved.
Show resolved Hide resolved
*
* Licensed 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
*
* https://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 dlp;

class ExampleClass {
public static void foo() {
System.out.println("bar");
}

/*
* @deprecated This method will be removed in the next major version.
* Use {@link #foo()} instead
* foo has the same functionality as foobar.
Neenu1995 marked this conversation as resolved.
Show resolved Hide resolved
*/
@Deprecated
public static void foobar() {
System.out.println("bar");
}

public static class InnerClass {
public void asdf() {
System.out.println("qwer");
}
}
}