1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "java/AnnotationProcessor.h"
18 #include "util/Util.h"
19 
20 #include <algorithm>
21 
22 namespace aapt {
23 
appendCommentLine(std::string & comment)24 void AnnotationProcessor::appendCommentLine(std::string& comment) {
25     static const std::string sDeprecated = "@deprecated";
26     static const std::string sSystemApi = "@SystemApi";
27 
28     if (comment.find(sDeprecated) != std::string::npos) {
29         mAnnotationBitMask |= kDeprecated;
30     }
31 
32     std::string::size_type idx = comment.find(sSystemApi);
33     if (idx != std::string::npos) {
34         mAnnotationBitMask |= kSystemApi;
35         comment.erase(comment.begin() + idx, comment.begin() + idx + sSystemApi.size());
36     }
37 
38     if (util::trimWhitespace(comment).empty()) {
39         return;
40     }
41 
42     if (!mHasComments) {
43         mHasComments = true;
44         mComment << "/**";
45     }
46 
47     mComment << "\n * " << std::move(comment);
48 }
49 
appendComment(const StringPiece16 & comment)50 void AnnotationProcessor::appendComment(const StringPiece16& comment) {
51     // We need to process line by line to clean-up whitespace and append prefixes.
52     for (StringPiece16 line : util::tokenize(comment, u'\n')) {
53         line = util::trimWhitespace(line);
54         if (!line.empty()) {
55             std::string utf8Line = util::utf16ToUtf8(line);
56             appendCommentLine(utf8Line);
57         }
58     }
59 }
60 
appendComment(const StringPiece & comment)61 void AnnotationProcessor::appendComment(const StringPiece& comment) {
62     for (StringPiece line : util::tokenize(comment, '\n')) {
63         line = util::trimWhitespace(line);
64         if (!line.empty()) {
65             std::string utf8Line = line.toString();
66             appendCommentLine(utf8Line);
67         }
68     }
69 }
70 
appendNewLine()71 void AnnotationProcessor::appendNewLine() {
72     mComment << "\n *";
73 }
74 
writeToStream(std::ostream * out,const StringPiece & prefix) const75 void AnnotationProcessor::writeToStream(std::ostream* out, const StringPiece& prefix) const {
76     if (mHasComments) {
77         std::string result = mComment.str();
78         for (StringPiece line : util::tokenize<char>(result, '\n')) {
79            *out << prefix << line << "\n";
80         }
81         *out << prefix << " */" << "\n";
82     }
83 
84     if (mAnnotationBitMask & kDeprecated) {
85         *out << prefix << "@Deprecated\n";
86     }
87 
88     if (mAnnotationBitMask & kSystemApi) {
89         *out << prefix << "@android.annotation.SystemApi\n";
90     }
91 }
92 
93 } // namespace aapt
94